PlanOpticon

planopticon / api / providers / 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/providers/">
16
17
18
<link rel="prev" href="../models/">
19
20
21
<link rel="next" href="../analyzers/">
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>Providers - 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="#providers-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
Providers
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
1252
1253
<li class="md-nav__item md-nav__item--active">
1254
1255
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
1256
1257
1258
1259
1260
1261
<label class="md-nav__link md-nav__link--active" for="__toc">
1262
1263
1264
1265
<span class="md-ellipsis">
1266
1267
1268
Providers
1269
1270
1271
1272
</span>
1273
1274
1275
1276
<span class="md-nav__icon md-icon"></span>
1277
</label>
1278
1279
<a href="./" class="md-nav__link md-nav__link--active">
1280
1281
1282
1283
<span class="md-ellipsis">
1284
1285
1286
Providers
1287
1288
1289
1290
</span>
1291
1292
1293
1294
</a>
1295
1296
1297
1298
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
1299
1300
1301
1302
1303
1304
1305
<label class="md-nav__title" for="__toc">
1306
<span class="md-nav__icon md-icon"></span>
1307
Table of contents
1308
</label>
1309
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
1310
1311
<li class="md-nav__item">
1312
<a href="#video_processor.providers.base" class="md-nav__link">
1313
<span class="md-ellipsis">
1314
1315
base
1316
1317
</span>
1318
</a>
1319
1320
<nav class="md-nav" aria-label="base">
1321
<ul class="md-nav__list">
1322
1323
<li class="md-nav__item">
1324
<a href="#video_processor.providers.base.BaseProvider" class="md-nav__link">
1325
<span class="md-ellipsis">
1326
1327
BaseProvider
1328
1329
</span>
1330
</a>
1331
1332
<nav class="md-nav" aria-label="BaseProvider">
1333
<ul class="md-nav__list">
1334
1335
<li class="md-nav__item">
1336
<a href="#video_processor.providers.base.BaseProvider.analyze_image" class="md-nav__link">
1337
<span class="md-ellipsis">
1338
1339
analyze_image
1340
1341
</span>
1342
</a>
1343
1344
</li>
1345
1346
<li class="md-nav__item">
1347
<a href="#video_processor.providers.base.BaseProvider.chat" class="md-nav__link">
1348
<span class="md-ellipsis">
1349
1350
chat
1351
1352
</span>
1353
</a>
1354
1355
</li>
1356
1357
<li class="md-nav__item">
1358
<a href="#video_processor.providers.base.BaseProvider.list_models" class="md-nav__link">
1359
<span class="md-ellipsis">
1360
1361
list_models
1362
1363
</span>
1364
</a>
1365
1366
</li>
1367
1368
<li class="md-nav__item">
1369
<a href="#video_processor.providers.base.BaseProvider.transcribe_audio" class="md-nav__link">
1370
<span class="md-ellipsis">
1371
1372
transcribe_audio
1373
1374
</span>
1375
</a>
1376
1377
</li>
1378
1379
</ul>
1380
</nav>
1381
1382
</li>
1383
1384
<li class="md-nav__item">
1385
<a href="#video_processor.providers.base.ModelInfo" class="md-nav__link">
1386
<span class="md-ellipsis">
1387
1388
ModelInfo
1389
1390
</span>
1391
</a>
1392
1393
</li>
1394
1395
<li class="md-nav__item">
1396
<a href="#video_processor.providers.base.OpenAICompatibleProvider" class="md-nav__link">
1397
<span class="md-ellipsis">
1398
1399
OpenAICompatibleProvider
1400
1401
</span>
1402
</a>
1403
1404
</li>
1405
1406
<li class="md-nav__item">
1407
<a href="#video_processor.providers.base.ProviderRegistry" class="md-nav__link">
1408
<span class="md-ellipsis">
1409
1410
ProviderRegistry
1411
1412
</span>
1413
</a>
1414
1415
<nav class="md-nav" aria-label="ProviderRegistry">
1416
<ul class="md-nav__list">
1417
1418
<li class="md-nav__item">
1419
<a href="#video_processor.providers.base.ProviderRegistry.all_registered" class="md-nav__link">
1420
<span class="md-ellipsis">
1421
1422
all_registered
1423
1424
</span>
1425
</a>
1426
1427
</li>
1428
1429
<li class="md-nav__item">
1430
<a href="#video_processor.providers.base.ProviderRegistry.available" class="md-nav__link">
1431
<span class="md-ellipsis">
1432
1433
available
1434
1435
</span>
1436
</a>
1437
1438
</li>
1439
1440
<li class="md-nav__item">
1441
<a href="#video_processor.providers.base.ProviderRegistry.get" class="md-nav__link">
1442
<span class="md-ellipsis">
1443
1444
get
1445
1446
</span>
1447
</a>
1448
1449
</li>
1450
1451
<li class="md-nav__item">
1452
<a href="#video_processor.providers.base.ProviderRegistry.get_by_model" class="md-nav__link">
1453
<span class="md-ellipsis">
1454
1455
get_by_model
1456
1457
</span>
1458
</a>
1459
1460
</li>
1461
1462
<li class="md-nav__item">
1463
<a href="#video_processor.providers.base.ProviderRegistry.get_default_models" class="md-nav__link">
1464
<span class="md-ellipsis">
1465
1466
get_default_models
1467
1468
</span>
1469
</a>
1470
1471
</li>
1472
1473
<li class="md-nav__item">
1474
<a href="#video_processor.providers.base.ProviderRegistry.register" class="md-nav__link">
1475
<span class="md-ellipsis">
1476
1477
register
1478
1479
</span>
1480
</a>
1481
1482
</li>
1483
1484
</ul>
1485
</nav>
1486
1487
</li>
1488
1489
</ul>
1490
</nav>
1491
1492
</li>
1493
1494
<li class="md-nav__item">
1495
<a href="#video_processor.providers.manager" class="md-nav__link">
1496
<span class="md-ellipsis">
1497
1498
manager
1499
1500
</span>
1501
</a>
1502
1503
<nav class="md-nav" aria-label="manager">
1504
<ul class="md-nav__list">
1505
1506
<li class="md-nav__item">
1507
<a href="#video_processor.providers.manager.ProviderManager" class="md-nav__link">
1508
<span class="md-ellipsis">
1509
1510
ProviderManager
1511
1512
</span>
1513
</a>
1514
1515
<nav class="md-nav" aria-label="ProviderManager">
1516
<ul class="md-nav__list">
1517
1518
<li class="md-nav__item">
1519
<a href="#video_processor.providers.manager.ProviderManager.__init__" class="md-nav__link">
1520
<span class="md-ellipsis">
1521
1522
__init__
1523
1524
</span>
1525
</a>
1526
1527
<nav class="md-nav" aria-label="__init__">
1528
<ul class="md-nav__list">
1529
1530
<li class="md-nav__item">
1531
<a href="#video_processor.providers.manager.ProviderManager.__init__--parameters" class="md-nav__link">
1532
<span class="md-ellipsis">
1533
1534
Parameters
1535
1536
</span>
1537
</a>
1538
1539
</li>
1540
1541
</ul>
1542
</nav>
1543
1544
</li>
1545
1546
<li class="md-nav__item">
1547
<a href="#video_processor.providers.manager.ProviderManager.analyze_image" class="md-nav__link">
1548
<span class="md-ellipsis">
1549
1550
analyze_image
1551
1552
</span>
1553
</a>
1554
1555
</li>
1556
1557
<li class="md-nav__item">
1558
<a href="#video_processor.providers.manager.ProviderManager.chat" class="md-nav__link">
1559
<span class="md-ellipsis">
1560
1561
chat
1562
1563
</span>
1564
</a>
1565
1566
</li>
1567
1568
<li class="md-nav__item">
1569
<a href="#video_processor.providers.manager.ProviderManager.get_models_used" class="md-nav__link">
1570
<span class="md-ellipsis">
1571
1572
get_models_used
1573
1574
</span>
1575
</a>
1576
1577
</li>
1578
1579
<li class="md-nav__item">
1580
<a href="#video_processor.providers.manager.ProviderManager.transcribe_audio" class="md-nav__link">
1581
<span class="md-ellipsis">
1582
1583
transcribe_audio
1584
1585
</span>
1586
</a>
1587
1588
</li>
1589
1590
</ul>
1591
</nav>
1592
1593
</li>
1594
1595
</ul>
1596
</nav>
1597
1598
</li>
1599
1600
<li class="md-nav__item">
1601
<a href="#video_processor.providers.discovery" class="md-nav__link">
1602
<span class="md-ellipsis">
1603
1604
discovery
1605
1606
</span>
1607
</a>
1608
1609
<nav class="md-nav" aria-label="discovery">
1610
<ul class="md-nav__list">
1611
1612
<li class="md-nav__item">
1613
<a href="#video_processor.providers.discovery.clear_discovery_cache" class="md-nav__link">
1614
<span class="md-ellipsis">
1615
1616
clear_discovery_cache
1617
1618
</span>
1619
</a>
1620
1621
</li>
1622
1623
<li class="md-nav__item">
1624
<a href="#video_processor.providers.discovery.discover_available_models" class="md-nav__link">
1625
<span class="md-ellipsis">
1626
1627
discover_available_models
1628
1629
</span>
1630
</a>
1631
1632
</li>
1633
1634
</ul>
1635
</nav>
1636
1637
</li>
1638
1639
<li class="md-nav__item">
1640
<a href="#overview" class="md-nav__link">
1641
<span class="md-ellipsis">
1642
1643
Overview
1644
1645
</span>
1646
</a>
1647
1648
</li>
1649
1650
<li class="md-nav__item">
1651
<a href="#baseprovider-abc" class="md-nav__link">
1652
<span class="md-ellipsis">
1653
1654
BaseProvider (ABC)
1655
1656
</span>
1657
</a>
1658
1659
<nav class="md-nav" aria-label="BaseProvider (ABC)">
1660
<ul class="md-nav__list">
1661
1662
<li class="md-nav__item">
1663
<a href="#chat" class="md-nav__link">
1664
<span class="md-ellipsis">
1665
1666
chat()
1667
1668
</span>
1669
</a>
1670
1671
</li>
1672
1673
<li class="md-nav__item">
1674
<a href="#analyze_image" class="md-nav__link">
1675
<span class="md-ellipsis">
1676
1677
analyze_image()
1678
1679
</span>
1680
</a>
1681
1682
</li>
1683
1684
<li class="md-nav__item">
1685
<a href="#transcribe_audio" class="md-nav__link">
1686
<span class="md-ellipsis">
1687
1688
transcribe_audio()
1689
1690
</span>
1691
</a>
1692
1693
</li>
1694
1695
<li class="md-nav__item">
1696
<a href="#list_models" class="md-nav__link">
1697
<span class="md-ellipsis">
1698
1699
list_models()
1700
1701
</span>
1702
</a>
1703
1704
</li>
1705
1706
</ul>
1707
</nav>
1708
1709
</li>
1710
1711
<li class="md-nav__item">
1712
<a href="#modelinfo" class="md-nav__link">
1713
<span class="md-ellipsis">
1714
1715
ModelInfo
1716
1717
</span>
1718
</a>
1719
1720
</li>
1721
1722
<li class="md-nav__item">
1723
<a href="#providerregistry" class="md-nav__link">
1724
<span class="md-ellipsis">
1725
1726
ProviderRegistry
1727
1728
</span>
1729
</a>
1730
1731
<nav class="md-nav" aria-label="ProviderRegistry">
1732
<ul class="md-nav__list">
1733
1734
<li class="md-nav__item">
1735
<a href="#register" class="md-nav__link">
1736
<span class="md-ellipsis">
1737
1738
register()
1739
1740
</span>
1741
</a>
1742
1743
</li>
1744
1745
<li class="md-nav__item">
1746
<a href="#get" class="md-nav__link">
1747
<span class="md-ellipsis">
1748
1749
get()
1750
1751
</span>
1752
</a>
1753
1754
</li>
1755
1756
<li class="md-nav__item">
1757
<a href="#get_by_model" class="md-nav__link">
1758
<span class="md-ellipsis">
1759
1760
get_by_model()
1761
1762
</span>
1763
</a>
1764
1765
</li>
1766
1767
<li class="md-nav__item">
1768
<a href="#get_default_models" class="md-nav__link">
1769
<span class="md-ellipsis">
1770
1771
get_default_models()
1772
1773
</span>
1774
</a>
1775
1776
</li>
1777
1778
<li class="md-nav__item">
1779
<a href="#available" class="md-nav__link">
1780
<span class="md-ellipsis">
1781
1782
available()
1783
1784
</span>
1785
</a>
1786
1787
</li>
1788
1789
<li class="md-nav__item">
1790
<a href="#all_registered" class="md-nav__link">
1791
<span class="md-ellipsis">
1792
1793
all_registered()
1794
1795
</span>
1796
</a>
1797
1798
</li>
1799
1800
</ul>
1801
</nav>
1802
1803
</li>
1804
1805
<li class="md-nav__item">
1806
<a href="#openaicompatibleprovider" class="md-nav__link">
1807
<span class="md-ellipsis">
1808
1809
OpenAICompatibleProvider
1810
1811
</span>
1812
</a>
1813
1814
</li>
1815
1816
<li class="md-nav__item">
1817
<a href="#providermanager" class="md-nav__link">
1818
<span class="md-ellipsis">
1819
1820
ProviderManager
1821
1822
</span>
1823
</a>
1824
1825
<nav class="md-nav" aria-label="ProviderManager">
1826
<ul class="md-nav__list">
1827
1828
<li class="md-nav__item">
1829
<a href="#constructor" class="md-nav__link">
1830
<span class="md-ellipsis">
1831
1832
Constructor
1833
1834
</span>
1835
</a>
1836
1837
</li>
1838
1839
<li class="md-nav__item">
1840
<a href="#auto-selection-preferences" class="md-nav__link">
1841
<span class="md-ellipsis">
1842
1843
Auto-selection preferences
1844
1845
</span>
1846
</a>
1847
1848
</li>
1849
1850
<li class="md-nav__item">
1851
<a href="#chat_1" class="md-nav__link">
1852
<span class="md-ellipsis">
1853
1854
chat()
1855
1856
</span>
1857
</a>
1858
1859
</li>
1860
1861
<li class="md-nav__item">
1862
<a href="#analyze_image_1" class="md-nav__link">
1863
<span class="md-ellipsis">
1864
1865
analyze_image()
1866
1867
</span>
1868
</a>
1869
1870
</li>
1871
1872
<li class="md-nav__item">
1873
<a href="#transcribe_audio_1" class="md-nav__link">
1874
<span class="md-ellipsis">
1875
1876
transcribe_audio()
1877
1878
</span>
1879
</a>
1880
1881
</li>
1882
1883
<li class="md-nav__item">
1884
<a href="#get_models_used" class="md-nav__link">
1885
<span class="md-ellipsis">
1886
1887
get_models_used()
1888
1889
</span>
1890
</a>
1891
1892
</li>
1893
1894
<li class="md-nav__item">
1895
<a href="#usage-examples" class="md-nav__link">
1896
<span class="md-ellipsis">
1897
1898
Usage examples
1899
1900
</span>
1901
</a>
1902
1903
</li>
1904
1905
</ul>
1906
</nav>
1907
1908
</li>
1909
1910
<li class="md-nav__item">
1911
<a href="#discover_available_models" class="md-nav__link">
1912
<span class="md-ellipsis">
1913
1914
discover_available_models()
1915
1916
</span>
1917
</a>
1918
1919
<nav class="md-nav" aria-label="discover_available_models()">
1920
<ul class="md-nav__list">
1921
1922
<li class="md-nav__item">
1923
<a href="#clear_discovery_cache" class="md-nav__link">
1924
<span class="md-ellipsis">
1925
1926
clear_discovery_cache()
1927
1928
</span>
1929
</a>
1930
1931
</li>
1932
1933
</ul>
1934
</nav>
1935
1936
</li>
1937
1938
<li class="md-nav__item">
1939
<a href="#built-in-providers" class="md-nav__link">
1940
<span class="md-ellipsis">
1941
1942
Built-in Providers
1943
1944
</span>
1945
</a>
1946
1947
</li>
1948
1949
</ul>
1950
1951
</nav>
1952
1953
</li>
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
<li class="md-nav__item">
1965
<a href="../analyzers/" class="md-nav__link">
1966
1967
1968
1969
<span class="md-ellipsis">
1970
1971
1972
Analyzers
1973
1974
1975
1976
</span>
1977
1978
1979
1980
</a>
1981
</li>
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
<li class="md-nav__item">
1993
<a href="../agent/" class="md-nav__link">
1994
1995
1996
1997
<span class="md-ellipsis">
1998
1999
2000
Agent & Skills
2001
2002
2003
2004
</span>
2005
2006
2007
2008
</a>
2009
</li>
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
<li class="md-nav__item">
2021
<a href="../sources/" class="md-nav__link">
2022
2023
2024
2025
<span class="md-ellipsis">
2026
2027
2028
Sources
2029
2030
2031
2032
</span>
2033
2034
2035
2036
</a>
2037
</li>
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
<li class="md-nav__item">
2049
<a href="../auth/" class="md-nav__link">
2050
2051
2052
2053
<span class="md-ellipsis">
2054
2055
2056
Authentication
2057
2058
2059
2060
</span>
2061
2062
2063
2064
</a>
2065
</li>
2066
2067
2068
2069
2070
</ul>
2071
</nav>
2072
2073
</li>
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
<li class="md-nav__item">
2084
<a href="../../faq/" class="md-nav__link">
2085
2086
2087
2088
<span class="md-ellipsis">
2089
2090
2091
FAQ & Troubleshooting
2092
2093
2094
2095
</span>
2096
2097
2098
2099
</a>
2100
</li>
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
<li class="md-nav__item">
2111
<a href="../../contributing/" class="md-nav__link">
2112
2113
2114
2115
<span class="md-ellipsis">
2116
2117
2118
Contributing
2119
2120
2121
2122
</span>
2123
2124
2125
2126
</a>
2127
</li>
2128
2129
2130
2131
</ul>
2132
</nav>
2133
</div>
2134
</div>
2135
</div>
2136
2137
2138
2139
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
2140
<div class="md-sidebar__scrollwrap">
2141
<div class="md-sidebar__inner">
2142
2143
2144
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
2145
2146
2147
2148
2149
2150
2151
<label class="md-nav__title" for="__toc">
2152
<span class="md-nav__icon md-icon"></span>
2153
Table of contents
2154
</label>
2155
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
2156
2157
<li class="md-nav__item">
2158
<a href="#video_processor.providers.base" class="md-nav__link">
2159
<span class="md-ellipsis">
2160
2161
base
2162
2163
</span>
2164
</a>
2165
2166
<nav class="md-nav" aria-label="base">
2167
<ul class="md-nav__list">
2168
2169
<li class="md-nav__item">
2170
<a href="#video_processor.providers.base.BaseProvider" class="md-nav__link">
2171
<span class="md-ellipsis">
2172
2173
BaseProvider
2174
2175
</span>
2176
</a>
2177
2178
<nav class="md-nav" aria-label="BaseProvider">
2179
<ul class="md-nav__list">
2180
2181
<li class="md-nav__item">
2182
<a href="#video_processor.providers.base.BaseProvider.analyze_image" class="md-nav__link">
2183
<span class="md-ellipsis">
2184
2185
analyze_image
2186
2187
</span>
2188
</a>
2189
2190
</li>
2191
2192
<li class="md-nav__item">
2193
<a href="#video_processor.providers.base.BaseProvider.chat" class="md-nav__link">
2194
<span class="md-ellipsis">
2195
2196
chat
2197
2198
</span>
2199
</a>
2200
2201
</li>
2202
2203
<li class="md-nav__item">
2204
<a href="#video_processor.providers.base.BaseProvider.list_models" class="md-nav__link">
2205
<span class="md-ellipsis">
2206
2207
list_models
2208
2209
</span>
2210
</a>
2211
2212
</li>
2213
2214
<li class="md-nav__item">
2215
<a href="#video_processor.providers.base.BaseProvider.transcribe_audio" class="md-nav__link">
2216
<span class="md-ellipsis">
2217
2218
transcribe_audio
2219
2220
</span>
2221
</a>
2222
2223
</li>
2224
2225
</ul>
2226
</nav>
2227
2228
</li>
2229
2230
<li class="md-nav__item">
2231
<a href="#video_processor.providers.base.ModelInfo" class="md-nav__link">
2232
<span class="md-ellipsis">
2233
2234
ModelInfo
2235
2236
</span>
2237
</a>
2238
2239
</li>
2240
2241
<li class="md-nav__item">
2242
<a href="#video_processor.providers.base.OpenAICompatibleProvider" class="md-nav__link">
2243
<span class="md-ellipsis">
2244
2245
OpenAICompatibleProvider
2246
2247
</span>
2248
</a>
2249
2250
</li>
2251
2252
<li class="md-nav__item">
2253
<a href="#video_processor.providers.base.ProviderRegistry" class="md-nav__link">
2254
<span class="md-ellipsis">
2255
2256
ProviderRegistry
2257
2258
</span>
2259
</a>
2260
2261
<nav class="md-nav" aria-label="ProviderRegistry">
2262
<ul class="md-nav__list">
2263
2264
<li class="md-nav__item">
2265
<a href="#video_processor.providers.base.ProviderRegistry.all_registered" class="md-nav__link">
2266
<span class="md-ellipsis">
2267
2268
all_registered
2269
2270
</span>
2271
</a>
2272
2273
</li>
2274
2275
<li class="md-nav__item">
2276
<a href="#video_processor.providers.base.ProviderRegistry.available" class="md-nav__link">
2277
<span class="md-ellipsis">
2278
2279
available
2280
2281
</span>
2282
</a>
2283
2284
</li>
2285
2286
<li class="md-nav__item">
2287
<a href="#video_processor.providers.base.ProviderRegistry.get" class="md-nav__link">
2288
<span class="md-ellipsis">
2289
2290
get
2291
2292
</span>
2293
</a>
2294
2295
</li>
2296
2297
<li class="md-nav__item">
2298
<a href="#video_processor.providers.base.ProviderRegistry.get_by_model" class="md-nav__link">
2299
<span class="md-ellipsis">
2300
2301
get_by_model
2302
2303
</span>
2304
</a>
2305
2306
</li>
2307
2308
<li class="md-nav__item">
2309
<a href="#video_processor.providers.base.ProviderRegistry.get_default_models" class="md-nav__link">
2310
<span class="md-ellipsis">
2311
2312
get_default_models
2313
2314
</span>
2315
</a>
2316
2317
</li>
2318
2319
<li class="md-nav__item">
2320
<a href="#video_processor.providers.base.ProviderRegistry.register" class="md-nav__link">
2321
<span class="md-ellipsis">
2322
2323
register
2324
2325
</span>
2326
</a>
2327
2328
</li>
2329
2330
</ul>
2331
</nav>
2332
2333
</li>
2334
2335
</ul>
2336
</nav>
2337
2338
</li>
2339
2340
<li class="md-nav__item">
2341
<a href="#video_processor.providers.manager" class="md-nav__link">
2342
<span class="md-ellipsis">
2343
2344
manager
2345
2346
</span>
2347
</a>
2348
2349
<nav class="md-nav" aria-label="manager">
2350
<ul class="md-nav__list">
2351
2352
<li class="md-nav__item">
2353
<a href="#video_processor.providers.manager.ProviderManager" class="md-nav__link">
2354
<span class="md-ellipsis">
2355
2356
ProviderManager
2357
2358
</span>
2359
</a>
2360
2361
<nav class="md-nav" aria-label="ProviderManager">
2362
<ul class="md-nav__list">
2363
2364
<li class="md-nav__item">
2365
<a href="#video_processor.providers.manager.ProviderManager.__init__" class="md-nav__link">
2366
<span class="md-ellipsis">
2367
2368
__init__
2369
2370
</span>
2371
</a>
2372
2373
<nav class="md-nav" aria-label="__init__">
2374
<ul class="md-nav__list">
2375
2376
<li class="md-nav__item">
2377
<a href="#video_processor.providers.manager.ProviderManager.__init__--parameters" class="md-nav__link">
2378
<span class="md-ellipsis">
2379
2380
Parameters
2381
2382
</span>
2383
</a>
2384
2385
</li>
2386
2387
</ul>
2388
</nav>
2389
2390
</li>
2391
2392
<li class="md-nav__item">
2393
<a href="#video_processor.providers.manager.ProviderManager.analyze_image" class="md-nav__link">
2394
<span class="md-ellipsis">
2395
2396
analyze_image
2397
2398
</span>
2399
</a>
2400
2401
</li>
2402
2403
<li class="md-nav__item">
2404
<a href="#video_processor.providers.manager.ProviderManager.chat" class="md-nav__link">
2405
<span class="md-ellipsis">
2406
2407
chat
2408
2409
</span>
2410
</a>
2411
2412
</li>
2413
2414
<li class="md-nav__item">
2415
<a href="#video_processor.providers.manager.ProviderManager.get_models_used" class="md-nav__link">
2416
<span class="md-ellipsis">
2417
2418
get_models_used
2419
2420
</span>
2421
</a>
2422
2423
</li>
2424
2425
<li class="md-nav__item">
2426
<a href="#video_processor.providers.manager.ProviderManager.transcribe_audio" class="md-nav__link">
2427
<span class="md-ellipsis">
2428
2429
transcribe_audio
2430
2431
</span>
2432
</a>
2433
2434
</li>
2435
2436
</ul>
2437
</nav>
2438
2439
</li>
2440
2441
</ul>
2442
</nav>
2443
2444
</li>
2445
2446
<li class="md-nav__item">
2447
<a href="#video_processor.providers.discovery" class="md-nav__link">
2448
<span class="md-ellipsis">
2449
2450
discovery
2451
2452
</span>
2453
</a>
2454
2455
<nav class="md-nav" aria-label="discovery">
2456
<ul class="md-nav__list">
2457
2458
<li class="md-nav__item">
2459
<a href="#video_processor.providers.discovery.clear_discovery_cache" class="md-nav__link">
2460
<span class="md-ellipsis">
2461
2462
clear_discovery_cache
2463
2464
</span>
2465
</a>
2466
2467
</li>
2468
2469
<li class="md-nav__item">
2470
<a href="#video_processor.providers.discovery.discover_available_models" class="md-nav__link">
2471
<span class="md-ellipsis">
2472
2473
discover_available_models
2474
2475
</span>
2476
</a>
2477
2478
</li>
2479
2480
</ul>
2481
</nav>
2482
2483
</li>
2484
2485
<li class="md-nav__item">
2486
<a href="#overview" class="md-nav__link">
2487
<span class="md-ellipsis">
2488
2489
Overview
2490
2491
</span>
2492
</a>
2493
2494
</li>
2495
2496
<li class="md-nav__item">
2497
<a href="#baseprovider-abc" class="md-nav__link">
2498
<span class="md-ellipsis">
2499
2500
BaseProvider (ABC)
2501
2502
</span>
2503
</a>
2504
2505
<nav class="md-nav" aria-label="BaseProvider (ABC)">
2506
<ul class="md-nav__list">
2507
2508
<li class="md-nav__item">
2509
<a href="#chat" class="md-nav__link">
2510
<span class="md-ellipsis">
2511
2512
chat()
2513
2514
</span>
2515
</a>
2516
2517
</li>
2518
2519
<li class="md-nav__item">
2520
<a href="#analyze_image" class="md-nav__link">
2521
<span class="md-ellipsis">
2522
2523
analyze_image()
2524
2525
</span>
2526
</a>
2527
2528
</li>
2529
2530
<li class="md-nav__item">
2531
<a href="#transcribe_audio" class="md-nav__link">
2532
<span class="md-ellipsis">
2533
2534
transcribe_audio()
2535
2536
</span>
2537
</a>
2538
2539
</li>
2540
2541
<li class="md-nav__item">
2542
<a href="#list_models" class="md-nav__link">
2543
<span class="md-ellipsis">
2544
2545
list_models()
2546
2547
</span>
2548
</a>
2549
2550
</li>
2551
2552
</ul>
2553
</nav>
2554
2555
</li>
2556
2557
<li class="md-nav__item">
2558
<a href="#modelinfo" class="md-nav__link">
2559
<span class="md-ellipsis">
2560
2561
ModelInfo
2562
2563
</span>
2564
</a>
2565
2566
</li>
2567
2568
<li class="md-nav__item">
2569
<a href="#providerregistry" class="md-nav__link">
2570
<span class="md-ellipsis">
2571
2572
ProviderRegistry
2573
2574
</span>
2575
</a>
2576
2577
<nav class="md-nav" aria-label="ProviderRegistry">
2578
<ul class="md-nav__list">
2579
2580
<li class="md-nav__item">
2581
<a href="#register" class="md-nav__link">
2582
<span class="md-ellipsis">
2583
2584
register()
2585
2586
</span>
2587
</a>
2588
2589
</li>
2590
2591
<li class="md-nav__item">
2592
<a href="#get" class="md-nav__link">
2593
<span class="md-ellipsis">
2594
2595
get()
2596
2597
</span>
2598
</a>
2599
2600
</li>
2601
2602
<li class="md-nav__item">
2603
<a href="#get_by_model" class="md-nav__link">
2604
<span class="md-ellipsis">
2605
2606
get_by_model()
2607
2608
</span>
2609
</a>
2610
2611
</li>
2612
2613
<li class="md-nav__item">
2614
<a href="#get_default_models" class="md-nav__link">
2615
<span class="md-ellipsis">
2616
2617
get_default_models()
2618
2619
</span>
2620
</a>
2621
2622
</li>
2623
2624
<li class="md-nav__item">
2625
<a href="#available" class="md-nav__link">
2626
<span class="md-ellipsis">
2627
2628
available()
2629
2630
</span>
2631
</a>
2632
2633
</li>
2634
2635
<li class="md-nav__item">
2636
<a href="#all_registered" class="md-nav__link">
2637
<span class="md-ellipsis">
2638
2639
all_registered()
2640
2641
</span>
2642
</a>
2643
2644
</li>
2645
2646
</ul>
2647
</nav>
2648
2649
</li>
2650
2651
<li class="md-nav__item">
2652
<a href="#openaicompatibleprovider" class="md-nav__link">
2653
<span class="md-ellipsis">
2654
2655
OpenAICompatibleProvider
2656
2657
</span>
2658
</a>
2659
2660
</li>
2661
2662
<li class="md-nav__item">
2663
<a href="#providermanager" class="md-nav__link">
2664
<span class="md-ellipsis">
2665
2666
ProviderManager
2667
2668
</span>
2669
</a>
2670
2671
<nav class="md-nav" aria-label="ProviderManager">
2672
<ul class="md-nav__list">
2673
2674
<li class="md-nav__item">
2675
<a href="#constructor" class="md-nav__link">
2676
<span class="md-ellipsis">
2677
2678
Constructor
2679
2680
</span>
2681
</a>
2682
2683
</li>
2684
2685
<li class="md-nav__item">
2686
<a href="#auto-selection-preferences" class="md-nav__link">
2687
<span class="md-ellipsis">
2688
2689
Auto-selection preferences
2690
2691
</span>
2692
</a>
2693
2694
</li>
2695
2696
<li class="md-nav__item">
2697
<a href="#chat_1" class="md-nav__link">
2698
<span class="md-ellipsis">
2699
2700
chat()
2701
2702
</span>
2703
</a>
2704
2705
</li>
2706
2707
<li class="md-nav__item">
2708
<a href="#analyze_image_1" class="md-nav__link">
2709
<span class="md-ellipsis">
2710
2711
analyze_image()
2712
2713
</span>
2714
</a>
2715
2716
</li>
2717
2718
<li class="md-nav__item">
2719
<a href="#transcribe_audio_1" class="md-nav__link">
2720
<span class="md-ellipsis">
2721
2722
transcribe_audio()
2723
2724
</span>
2725
</a>
2726
2727
</li>
2728
2729
<li class="md-nav__item">
2730
<a href="#get_models_used" class="md-nav__link">
2731
<span class="md-ellipsis">
2732
2733
get_models_used()
2734
2735
</span>
2736
</a>
2737
2738
</li>
2739
2740
<li class="md-nav__item">
2741
<a href="#usage-examples" class="md-nav__link">
2742
<span class="md-ellipsis">
2743
2744
Usage examples
2745
2746
</span>
2747
</a>
2748
2749
</li>
2750
2751
</ul>
2752
</nav>
2753
2754
</li>
2755
2756
<li class="md-nav__item">
2757
<a href="#discover_available_models" class="md-nav__link">
2758
<span class="md-ellipsis">
2759
2760
discover_available_models()
2761
2762
</span>
2763
</a>
2764
2765
<nav class="md-nav" aria-label="discover_available_models()">
2766
<ul class="md-nav__list">
2767
2768
<li class="md-nav__item">
2769
<a href="#clear_discovery_cache" class="md-nav__link">
2770
<span class="md-ellipsis">
2771
2772
clear_discovery_cache()
2773
2774
</span>
2775
</a>
2776
2777
</li>
2778
2779
</ul>
2780
</nav>
2781
2782
</li>
2783
2784
<li class="md-nav__item">
2785
<a href="#built-in-providers" class="md-nav__link">
2786
<span class="md-ellipsis">
2787
2788
Built-in Providers
2789
2790
</span>
2791
</a>
2792
2793
</li>
2794
2795
</ul>
2796
2797
</nav>
2798
</div>
2799
</div>
2800
</div>
2801
2802
2803
2804
<div class="md-content" data-md-component="content">
2805
2806
<article class="md-content__inner md-typeset">
2807
2808
2809
2810
2811
2812
2813
2814
2815
<h1 id="providers-api-reference">Providers API Reference<a class="headerlink" href="#providers-api-reference" title="Permanent link">&para;</a></h1>
2816
2817
2818
<div class="doc doc-object doc-module">
2819
2820
2821
2822
<h2 id="video_processor.providers.base" class="doc doc-heading">
2823
<code>video_processor.providers.base</code>
2824
2825
2826
<a href="#video_processor.providers.base" class="headerlink" title="Permanent link">&para;</a></h2>
2827
2828
<div class="doc doc-contents first">
2829
2830
<p>Abstract base class, registry, and shared types for provider implementations.</p>
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
<div class="doc doc-children">
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
<div class="doc doc-object doc-class">
2852
2853
2854
2855
<h3 id="video_processor.providers.base.BaseProvider" class="doc doc-heading">
2856
<code>BaseProvider</code>
2857
2858
2859
<a href="#video_processor.providers.base.BaseProvider" class="headerlink" title="Permanent link">&para;</a></h3>
2860
2861
2862
<div class="doc doc-contents ">
2863
<p class="doc doc-class-bases">
2864
Bases: <code><span title="abc.ABC">ABC</span></code></p>
2865
2866
2867
2868
<p>Abstract base for all provider implementations.</p>
2869
2870
2871
2872
2873
2874
2875
2876
2877
<details class="mkdocstrings-source">
2878
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
2879
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-26">26</a></span>
2880
<span class="normal"><a href="#__codelineno-0-27">27</a></span>
2881
<span class="normal"><a href="#__codelineno-0-28">28</a></span>
2882
<span class="normal"><a href="#__codelineno-0-29">29</a></span>
2883
<span class="normal"><a href="#__codelineno-0-30">30</a></span>
2884
<span class="normal"><a href="#__codelineno-0-31">31</a></span>
2885
<span class="normal"><a href="#__codelineno-0-32">32</a></span>
2886
<span class="normal"><a href="#__codelineno-0-33">33</a></span>
2887
<span class="normal"><a href="#__codelineno-0-34">34</a></span>
2888
<span class="normal"><a href="#__codelineno-0-35">35</a></span>
2889
<span class="normal"><a href="#__codelineno-0-36">36</a></span>
2890
<span class="normal"><a href="#__codelineno-0-37">37</a></span>
2891
<span class="normal"><a href="#__codelineno-0-38">38</a></span>
2892
<span class="normal"><a href="#__codelineno-0-39">39</a></span>
2893
<span class="normal"><a href="#__codelineno-0-40">40</a></span>
2894
<span class="normal"><a href="#__codelineno-0-41">41</a></span>
2895
<span class="normal"><a href="#__codelineno-0-42">42</a></span>
2896
<span class="normal"><a href="#__codelineno-0-43">43</a></span>
2897
<span class="normal"><a href="#__codelineno-0-44">44</a></span>
2898
<span class="normal"><a href="#__codelineno-0-45">45</a></span>
2899
<span class="normal"><a href="#__codelineno-0-46">46</a></span>
2900
<span class="normal"><a href="#__codelineno-0-47">47</a></span>
2901
<span class="normal"><a href="#__codelineno-0-48">48</a></span>
2902
<span class="normal"><a href="#__codelineno-0-49">49</a></span>
2903
<span class="normal"><a href="#__codelineno-0-50">50</a></span>
2904
<span class="normal"><a href="#__codelineno-0-51">51</a></span>
2905
<span class="normal"><a href="#__codelineno-0-52">52</a></span>
2906
<span class="normal"><a href="#__codelineno-0-53">53</a></span>
2907
<span class="normal"><a href="#__codelineno-0-54">54</a></span>
2908
<span class="normal"><a href="#__codelineno-0-55">55</a></span>
2909
<span class="normal"><a href="#__codelineno-0-56">56</a></span>
2910
<span class="normal"><a href="#__codelineno-0-57">57</a></span>
2911
<span class="normal"><a href="#__codelineno-0-58">58</a></span>
2912
<span class="normal"><a href="#__codelineno-0-59">59</a></span>
2913
<span class="normal"><a href="#__codelineno-0-60">60</a></span>
2914
<span class="normal"><a href="#__codelineno-0-61">61</a></span>
2915
<span class="normal"><a href="#__codelineno-0-62">62</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-26" name="__codelineno-0-26"></a><span class="k">class</span><span class="w"> </span><span class="nc">BaseProvider</span><span class="p">(</span><span class="n">ABC</span><span class="p">):</span>
2916
<a id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Abstract base for all provider implementations.&quot;&quot;&quot;</span>
2917
<a id="__codelineno-0-28" name="__codelineno-0-28"></a>
2918
<a id="__codelineno-0-29" name="__codelineno-0-29"></a> <span class="n">provider_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
2919
<a id="__codelineno-0-30" name="__codelineno-0-30"></a>
2920
<a id="__codelineno-0-31" name="__codelineno-0-31"></a> <span class="nd">@abstractmethod</span>
2921
<a id="__codelineno-0-32" name="__codelineno-0-32"></a> <span class="k">def</span><span class="w"> </span><span class="nf">chat</span><span class="p">(</span>
2922
<a id="__codelineno-0-33" name="__codelineno-0-33"></a> <span class="bp">self</span><span class="p">,</span>
2923
<a id="__codelineno-0-34" name="__codelineno-0-34"></a> <span class="n">messages</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">dict</span><span class="p">],</span>
2924
<a id="__codelineno-0-35" name="__codelineno-0-35"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
2925
<a id="__codelineno-0-36" name="__codelineno-0-36"></a> <span class="n">temperature</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.7</span><span class="p">,</span>
2926
<a id="__codelineno-0-37" name="__codelineno-0-37"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
2927
<a id="__codelineno-0-38" name="__codelineno-0-38"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
2928
<a id="__codelineno-0-39" name="__codelineno-0-39"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a chat completion request. Returns the assistant text.&quot;&quot;&quot;</span>
2929
<a id="__codelineno-0-40" name="__codelineno-0-40"></a>
2930
<a id="__codelineno-0-41" name="__codelineno-0-41"></a> <span class="nd">@abstractmethod</span>
2931
<a id="__codelineno-0-42" name="__codelineno-0-42"></a> <span class="k">def</span><span class="w"> </span><span class="nf">analyze_image</span><span class="p">(</span>
2932
<a id="__codelineno-0-43" name="__codelineno-0-43"></a> <span class="bp">self</span><span class="p">,</span>
2933
<a id="__codelineno-0-44" name="__codelineno-0-44"></a> <span class="n">image_bytes</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span>
2934
<a id="__codelineno-0-45" name="__codelineno-0-45"></a> <span class="n">prompt</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
2935
<a id="__codelineno-0-46" name="__codelineno-0-46"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
2936
<a id="__codelineno-0-47" name="__codelineno-0-47"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
2937
<a id="__codelineno-0-48" name="__codelineno-0-48"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
2938
<a id="__codelineno-0-49" name="__codelineno-0-49"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Analyze an image with a prompt. Returns the assistant text.&quot;&quot;&quot;</span>
2939
<a id="__codelineno-0-50" name="__codelineno-0-50"></a>
2940
<a id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="nd">@abstractmethod</span>
2941
<a id="__codelineno-0-52" name="__codelineno-0-52"></a> <span class="k">def</span><span class="w"> </span><span class="nf">transcribe_audio</span><span class="p">(</span>
2942
<a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="bp">self</span><span class="p">,</span>
2943
<a id="__codelineno-0-54" name="__codelineno-0-54"></a> <span class="n">audio_path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Path</span><span class="p">,</span>
2944
<a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="n">language</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
2945
<a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
2946
<a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
2947
<a id="__codelineno-0-58" name="__codelineno-0-58"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Transcribe an audio file. Returns dict with &#39;text&#39;, &#39;segments&#39;, etc.&quot;&quot;&quot;</span>
2948
<a id="__codelineno-0-59" name="__codelineno-0-59"></a>
2949
<a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="nd">@abstractmethod</span>
2950
<a id="__codelineno-0-61" name="__codelineno-0-61"></a> <span class="k">def</span><span class="w"> </span><span class="nf">list_models</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ModelInfo</span><span class="p">]:</span>
2951
<a id="__codelineno-0-62" name="__codelineno-0-62"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Discover available models from this provider&#39;s API.&quot;&quot;&quot;</span>
2952
</code></pre></div></td></tr></table></div>
2953
</details>
2954
2955
2956
2957
<div class="doc doc-children">
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
<div class="doc doc-object doc-function">
2969
2970
2971
<h4 id="video_processor.providers.base.BaseProvider.analyze_image" class="doc doc-heading">
2972
<code class="highlight language-python"><span class="n">analyze_image</span><span class="p">(</span><span class="n">image_bytes</span><span class="p">,</span> <span class="n">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> <span class="n">model</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code>
2973
2974
<span class="doc doc-labels">
2975
<small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small>
2976
</span>
2977
2978
<a href="#video_processor.providers.base.BaseProvider.analyze_image" class="headerlink" title="Permanent link">&para;</a></h4>
2979
2980
2981
<div class="doc doc-contents ">
2982
2983
<p>Analyze an image with a prompt. Returns the assistant text.</p>
2984
2985
2986
<details class="mkdocstrings-source">
2987
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
2988
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-41">41</a></span>
2989
<span class="normal"><a href="#__codelineno-0-42">42</a></span>
2990
<span class="normal"><a href="#__codelineno-0-43">43</a></span>
2991
<span class="normal"><a href="#__codelineno-0-44">44</a></span>
2992
<span class="normal"><a href="#__codelineno-0-45">45</a></span>
2993
<span class="normal"><a href="#__codelineno-0-46">46</a></span>
2994
<span class="normal"><a href="#__codelineno-0-47">47</a></span>
2995
<span class="normal"><a href="#__codelineno-0-48">48</a></span>
2996
<span class="normal"><a href="#__codelineno-0-49">49</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-41" name="__codelineno-0-41"></a><span class="nd">@abstractmethod</span>
2997
<a id="__codelineno-0-42" name="__codelineno-0-42"></a><span class="k">def</span><span class="w"> </span><span class="nf">analyze_image</span><span class="p">(</span>
2998
<a id="__codelineno-0-43" name="__codelineno-0-43"></a> <span class="bp">self</span><span class="p">,</span>
2999
<a id="__codelineno-0-44" name="__codelineno-0-44"></a> <span class="n">image_bytes</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span>
3000
<a id="__codelineno-0-45" name="__codelineno-0-45"></a> <span class="n">prompt</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
3001
<a id="__codelineno-0-46" name="__codelineno-0-46"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
3002
<a id="__codelineno-0-47" name="__codelineno-0-47"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3003
<a id="__codelineno-0-48" name="__codelineno-0-48"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
3004
<a id="__codelineno-0-49" name="__codelineno-0-49"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Analyze an image with a prompt. Returns the assistant text.&quot;&quot;&quot;</span>
3005
</code></pre></div></td></tr></table></div>
3006
</details>
3007
</div>
3008
3009
</div>
3010
3011
<div class="doc doc-object doc-function">
3012
3013
3014
<h4 id="video_processor.providers.base.BaseProvider.chat" class="doc doc-heading">
3015
<code class="highlight language-python"><span class="n">chat</span><span class="p">(</span><span class="n">messages</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">4096</span><span class="p">,</span> <span class="n">temperature</span><span class="o">=</span><span class="mf">0.7</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code>
3016
3017
<span class="doc doc-labels">
3018
<small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small>
3019
</span>
3020
3021
<a href="#video_processor.providers.base.BaseProvider.chat" class="headerlink" title="Permanent link">&para;</a></h4>
3022
3023
3024
<div class="doc doc-contents ">
3025
3026
<p>Send a chat completion request. Returns the assistant text.</p>
3027
3028
3029
<details class="mkdocstrings-source">
3030
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3031
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-31">31</a></span>
3032
<span class="normal"><a href="#__codelineno-0-32">32</a></span>
3033
<span class="normal"><a href="#__codelineno-0-33">33</a></span>
3034
<span class="normal"><a href="#__codelineno-0-34">34</a></span>
3035
<span class="normal"><a href="#__codelineno-0-35">35</a></span>
3036
<span class="normal"><a href="#__codelineno-0-36">36</a></span>
3037
<span class="normal"><a href="#__codelineno-0-37">37</a></span>
3038
<span class="normal"><a href="#__codelineno-0-38">38</a></span>
3039
<span class="normal"><a href="#__codelineno-0-39">39</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="nd">@abstractmethod</span>
3040
<a id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="k">def</span><span class="w"> </span><span class="nf">chat</span><span class="p">(</span>
3041
<a id="__codelineno-0-33" name="__codelineno-0-33"></a> <span class="bp">self</span><span class="p">,</span>
3042
<a id="__codelineno-0-34" name="__codelineno-0-34"></a> <span class="n">messages</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">dict</span><span class="p">],</span>
3043
<a id="__codelineno-0-35" name="__codelineno-0-35"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
3044
<a id="__codelineno-0-36" name="__codelineno-0-36"></a> <span class="n">temperature</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.7</span><span class="p">,</span>
3045
<a id="__codelineno-0-37" name="__codelineno-0-37"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3046
<a id="__codelineno-0-38" name="__codelineno-0-38"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
3047
<a id="__codelineno-0-39" name="__codelineno-0-39"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a chat completion request. Returns the assistant text.&quot;&quot;&quot;</span>
3048
</code></pre></div></td></tr></table></div>
3049
</details>
3050
</div>
3051
3052
</div>
3053
3054
<div class="doc doc-object doc-function">
3055
3056
3057
<h4 id="video_processor.providers.base.BaseProvider.list_models" class="doc doc-heading">
3058
<code class="highlight language-python"><span class="n">list_models</span><span class="p">()</span></code>
3059
3060
<span class="doc doc-labels">
3061
<small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small>
3062
</span>
3063
3064
<a href="#video_processor.providers.base.BaseProvider.list_models" class="headerlink" title="Permanent link">&para;</a></h4>
3065
3066
3067
<div class="doc doc-contents ">
3068
3069
<p>Discover available models from this provider's API.</p>
3070
3071
3072
<details class="mkdocstrings-source">
3073
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3074
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-60">60</a></span>
3075
<span class="normal"><a href="#__codelineno-0-61">61</a></span>
3076
<span class="normal"><a href="#__codelineno-0-62">62</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-60" name="__codelineno-0-60"></a><span class="nd">@abstractmethod</span>
3077
<a id="__codelineno-0-61" name="__codelineno-0-61"></a><span class="k">def</span><span class="w"> </span><span class="nf">list_models</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ModelInfo</span><span class="p">]:</span>
3078
<a id="__codelineno-0-62" name="__codelineno-0-62"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Discover available models from this provider&#39;s API.&quot;&quot;&quot;</span>
3079
</code></pre></div></td></tr></table></div>
3080
</details>
3081
</div>
3082
3083
</div>
3084
3085
<div class="doc doc-object doc-function">
3086
3087
3088
<h4 id="video_processor.providers.base.BaseProvider.transcribe_audio" class="doc doc-heading">
3089
<code class="highlight language-python"><span class="n">transcribe_audio</span><span class="p">(</span><span class="n">audio_path</span><span class="p">,</span> <span class="n">language</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code>
3090
3091
<span class="doc doc-labels">
3092
<small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small>
3093
</span>
3094
3095
<a href="#video_processor.providers.base.BaseProvider.transcribe_audio" class="headerlink" title="Permanent link">&para;</a></h4>
3096
3097
3098
<div class="doc doc-contents ">
3099
3100
<p>Transcribe an audio file. Returns dict with 'text', 'segments', etc.</p>
3101
3102
3103
<details class="mkdocstrings-source">
3104
<summary>Source code in <code>video_processor/providers/base.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-51">51</a></span>
3106
<span class="normal"><a href="#__codelineno-0-52">52</a></span>
3107
<span class="normal"><a href="#__codelineno-0-53">53</a></span>
3108
<span class="normal"><a href="#__codelineno-0-54">54</a></span>
3109
<span class="normal"><a href="#__codelineno-0-55">55</a></span>
3110
<span class="normal"><a href="#__codelineno-0-56">56</a></span>
3111
<span class="normal"><a href="#__codelineno-0-57">57</a></span>
3112
<span class="normal"><a href="#__codelineno-0-58">58</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-51" name="__codelineno-0-51"></a><span class="nd">@abstractmethod</span>
3113
<a id="__codelineno-0-52" name="__codelineno-0-52"></a><span class="k">def</span><span class="w"> </span><span class="nf">transcribe_audio</span><span class="p">(</span>
3114
<a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="bp">self</span><span class="p">,</span>
3115
<a id="__codelineno-0-54" name="__codelineno-0-54"></a> <span class="n">audio_path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Path</span><span class="p">,</span>
3116
<a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="n">language</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3117
<a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3118
<a id="__codelineno-0-57" name="__codelineno-0-57"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
3119
<a id="__codelineno-0-58" name="__codelineno-0-58"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Transcribe an audio file. Returns dict with &#39;text&#39;, &#39;segments&#39;, etc.&quot;&quot;&quot;</span>
3120
</code></pre></div></td></tr></table></div>
3121
</details>
3122
</div>
3123
3124
</div>
3125
3126
3127
3128
</div>
3129
3130
</div>
3131
3132
</div>
3133
3134
<div class="doc doc-object doc-class">
3135
3136
3137
3138
<h3 id="video_processor.providers.base.ModelInfo" class="doc doc-heading">
3139
<code>ModelInfo</code>
3140
3141
3142
<a href="#video_processor.providers.base.ModelInfo" class="headerlink" title="Permanent link">&para;</a></h3>
3143
3144
3145
<div class="doc doc-contents ">
3146
<p class="doc doc-class-bases">
3147
Bases: <code><span title="pydantic.BaseModel">BaseModel</span></code></p>
3148
3149
3150
3151
<p>Information about an available model.</p>
3152
3153
3154
3155
3156
3157
3158
3159
3160
<details class="mkdocstrings-source">
3161
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3162
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-15">15</a></span>
3163
<span class="normal"><a href="#__codelineno-0-16">16</a></span>
3164
<span class="normal"><a href="#__codelineno-0-17">17</a></span>
3165
<span class="normal"><a href="#__codelineno-0-18">18</a></span>
3166
<span class="normal"><a href="#__codelineno-0-19">19</a></span>
3167
<span class="normal"><a href="#__codelineno-0-20">20</a></span>
3168
<span class="normal"><a href="#__codelineno-0-21">21</a></span>
3169
<span class="normal"><a href="#__codelineno-0-22">22</a></span>
3170
<span class="normal"><a href="#__codelineno-0-23">23</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="k">class</span><span class="w"> </span><span class="nc">ModelInfo</span><span class="p">(</span><span class="n">BaseModel</span><span class="p">):</span>
3171
<a id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Information about an available model.&quot;&quot;&quot;</span>
3172
<a id="__codelineno-0-17" name="__codelineno-0-17"></a>
3173
<a id="__codelineno-0-18" name="__codelineno-0-18"></a> <span class="nb">id</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;Model identifier (e.g. gpt-4o)&quot;</span><span class="p">)</span>
3174
<a id="__codelineno-0-19" name="__codelineno-0-19"></a> <span class="n">provider</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;Provider name (openai, anthropic, gemini)&quot;</span><span class="p">)</span>
3175
<a id="__codelineno-0-20" name="__codelineno-0-20"></a> <span class="n">display_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s2">&quot;Human-readable name&quot;</span><span class="p">)</span>
3176
<a id="__codelineno-0-21" name="__codelineno-0-21"></a> <span class="n">capabilities</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span>
3177
<a id="__codelineno-0-22" name="__codelineno-0-22"></a> <span class="n">default_factory</span><span class="o">=</span><span class="nb">list</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s2">&quot;Model capabilities: chat, vision, audio, embedding&quot;</span>
3178
<a id="__codelineno-0-23" name="__codelineno-0-23"></a> <span class="p">)</span>
3179
</code></pre></div></td></tr></table></div>
3180
</details>
3181
3182
3183
3184
<div class="doc doc-children">
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
</div>
3198
3199
</div>
3200
3201
</div>
3202
3203
<div class="doc doc-object doc-class">
3204
3205
3206
3207
<h3 id="video_processor.providers.base.OpenAICompatibleProvider" class="doc doc-heading">
3208
<code>OpenAICompatibleProvider</code>
3209
3210
3211
<a href="#video_processor.providers.base.OpenAICompatibleProvider" class="headerlink" title="Permanent link">&para;</a></h3>
3212
3213
3214
<div class="doc doc-contents ">
3215
<p class="doc doc-class-bases">
3216
Bases: <code><a class="autorefs autorefs-internal" title="BaseProvider (video_processor.providers.base.BaseProvider)" href="#video_processor.providers.base.BaseProvider">BaseProvider</a></code></p>
3217
3218
3219
3220
<p>Base for providers using OpenAI-compatible APIs.</p>
3221
<p>Suitable for Together, Fireworks, Cerebras, xAI, Azure, and similar services.</p>
3222
3223
3224
3225
3226
3227
3228
3229
3230
<details class="mkdocstrings-source">
3231
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3232
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-129">129</a></span>
3233
<span class="normal"><a href="#__codelineno-0-130">130</a></span>
3234
<span class="normal"><a href="#__codelineno-0-131">131</a></span>
3235
<span class="normal"><a href="#__codelineno-0-132">132</a></span>
3236
<span class="normal"><a href="#__codelineno-0-133">133</a></span>
3237
<span class="normal"><a href="#__codelineno-0-134">134</a></span>
3238
<span class="normal"><a href="#__codelineno-0-135">135</a></span>
3239
<span class="normal"><a href="#__codelineno-0-136">136</a></span>
3240
<span class="normal"><a href="#__codelineno-0-137">137</a></span>
3241
<span class="normal"><a href="#__codelineno-0-138">138</a></span>
3242
<span class="normal"><a href="#__codelineno-0-139">139</a></span>
3243
<span class="normal"><a href="#__codelineno-0-140">140</a></span>
3244
<span class="normal"><a href="#__codelineno-0-141">141</a></span>
3245
<span class="normal"><a href="#__codelineno-0-142">142</a></span>
3246
<span class="normal"><a href="#__codelineno-0-143">143</a></span>
3247
<span class="normal"><a href="#__codelineno-0-144">144</a></span>
3248
<span class="normal"><a href="#__codelineno-0-145">145</a></span>
3249
<span class="normal"><a href="#__codelineno-0-146">146</a></span>
3250
<span class="normal"><a href="#__codelineno-0-147">147</a></span>
3251
<span class="normal"><a href="#__codelineno-0-148">148</a></span>
3252
<span class="normal"><a href="#__codelineno-0-149">149</a></span>
3253
<span class="normal"><a href="#__codelineno-0-150">150</a></span>
3254
<span class="normal"><a href="#__codelineno-0-151">151</a></span>
3255
<span class="normal"><a href="#__codelineno-0-152">152</a></span>
3256
<span class="normal"><a href="#__codelineno-0-153">153</a></span>
3257
<span class="normal"><a href="#__codelineno-0-154">154</a></span>
3258
<span class="normal"><a href="#__codelineno-0-155">155</a></span>
3259
<span class="normal"><a href="#__codelineno-0-156">156</a></span>
3260
<span class="normal"><a href="#__codelineno-0-157">157</a></span>
3261
<span class="normal"><a href="#__codelineno-0-158">158</a></span>
3262
<span class="normal"><a href="#__codelineno-0-159">159</a></span>
3263
<span class="normal"><a href="#__codelineno-0-160">160</a></span>
3264
<span class="normal"><a href="#__codelineno-0-161">161</a></span>
3265
<span class="normal"><a href="#__codelineno-0-162">162</a></span>
3266
<span class="normal"><a href="#__codelineno-0-163">163</a></span>
3267
<span class="normal"><a href="#__codelineno-0-164">164</a></span>
3268
<span class="normal"><a href="#__codelineno-0-165">165</a></span>
3269
<span class="normal"><a href="#__codelineno-0-166">166</a></span>
3270
<span class="normal"><a href="#__codelineno-0-167">167</a></span>
3271
<span class="normal"><a href="#__codelineno-0-168">168</a></span>
3272
<span class="normal"><a href="#__codelineno-0-169">169</a></span>
3273
<span class="normal"><a href="#__codelineno-0-170">170</a></span>
3274
<span class="normal"><a href="#__codelineno-0-171">171</a></span>
3275
<span class="normal"><a href="#__codelineno-0-172">172</a></span>
3276
<span class="normal"><a href="#__codelineno-0-173">173</a></span>
3277
<span class="normal"><a href="#__codelineno-0-174">174</a></span>
3278
<span class="normal"><a href="#__codelineno-0-175">175</a></span>
3279
<span class="normal"><a href="#__codelineno-0-176">176</a></span>
3280
<span class="normal"><a href="#__codelineno-0-177">177</a></span>
3281
<span class="normal"><a href="#__codelineno-0-178">178</a></span>
3282
<span class="normal"><a href="#__codelineno-0-179">179</a></span>
3283
<span class="normal"><a href="#__codelineno-0-180">180</a></span>
3284
<span class="normal"><a href="#__codelineno-0-181">181</a></span>
3285
<span class="normal"><a href="#__codelineno-0-182">182</a></span>
3286
<span class="normal"><a href="#__codelineno-0-183">183</a></span>
3287
<span class="normal"><a href="#__codelineno-0-184">184</a></span>
3288
<span class="normal"><a href="#__codelineno-0-185">185</a></span>
3289
<span class="normal"><a href="#__codelineno-0-186">186</a></span>
3290
<span class="normal"><a href="#__codelineno-0-187">187</a></span>
3291
<span class="normal"><a href="#__codelineno-0-188">188</a></span>
3292
<span class="normal"><a href="#__codelineno-0-189">189</a></span>
3293
<span class="normal"><a href="#__codelineno-0-190">190</a></span>
3294
<span class="normal"><a href="#__codelineno-0-191">191</a></span>
3295
<span class="normal"><a href="#__codelineno-0-192">192</a></span>
3296
<span class="normal"><a href="#__codelineno-0-193">193</a></span>
3297
<span class="normal"><a href="#__codelineno-0-194">194</a></span>
3298
<span class="normal"><a href="#__codelineno-0-195">195</a></span>
3299
<span class="normal"><a href="#__codelineno-0-196">196</a></span>
3300
<span class="normal"><a href="#__codelineno-0-197">197</a></span>
3301
<span class="normal"><a href="#__codelineno-0-198">198</a></span>
3302
<span class="normal"><a href="#__codelineno-0-199">199</a></span>
3303
<span class="normal"><a href="#__codelineno-0-200">200</a></span>
3304
<span class="normal"><a href="#__codelineno-0-201">201</a></span>
3305
<span class="normal"><a href="#__codelineno-0-202">202</a></span>
3306
<span class="normal"><a href="#__codelineno-0-203">203</a></span>
3307
<span class="normal"><a href="#__codelineno-0-204">204</a></span>
3308
<span class="normal"><a href="#__codelineno-0-205">205</a></span>
3309
<span class="normal"><a href="#__codelineno-0-206">206</a></span>
3310
<span class="normal"><a href="#__codelineno-0-207">207</a></span>
3311
<span class="normal"><a href="#__codelineno-0-208">208</a></span>
3312
<span class="normal"><a href="#__codelineno-0-209">209</a></span>
3313
<span class="normal"><a href="#__codelineno-0-210">210</a></span>
3314
<span class="normal"><a href="#__codelineno-0-211">211</a></span>
3315
<span class="normal"><a href="#__codelineno-0-212">212</a></span>
3316
<span class="normal"><a href="#__codelineno-0-213">213</a></span>
3317
<span class="normal"><a href="#__codelineno-0-214">214</a></span>
3318
<span class="normal"><a href="#__codelineno-0-215">215</a></span>
3319
<span class="normal"><a href="#__codelineno-0-216">216</a></span>
3320
<span class="normal"><a href="#__codelineno-0-217">217</a></span>
3321
<span class="normal"><a href="#__codelineno-0-218">218</a></span>
3322
<span class="normal"><a href="#__codelineno-0-219">219</a></span>
3323
<span class="normal"><a href="#__codelineno-0-220">220</a></span>
3324
<span class="normal"><a href="#__codelineno-0-221">221</a></span>
3325
<span class="normal"><a href="#__codelineno-0-222">222</a></span>
3326
<span class="normal"><a href="#__codelineno-0-223">223</a></span>
3327
<span class="normal"><a href="#__codelineno-0-224">224</a></span>
3328
<span class="normal"><a href="#__codelineno-0-225">225</a></span>
3329
<span class="normal"><a href="#__codelineno-0-226">226</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-129" name="__codelineno-0-129"></a><span class="k">class</span><span class="w"> </span><span class="nc">OpenAICompatibleProvider</span><span class="p">(</span><span class="n">BaseProvider</span><span class="p">):</span>
3330
<a id="__codelineno-0-130" name="__codelineno-0-130"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Base for providers using OpenAI-compatible APIs.</span>
3331
<a id="__codelineno-0-131" name="__codelineno-0-131"></a>
3332
<a id="__codelineno-0-132" name="__codelineno-0-132"></a><span class="sd"> Suitable for Together, Fireworks, Cerebras, xAI, Azure, and similar services.</span>
3333
<a id="__codelineno-0-133" name="__codelineno-0-133"></a><span class="sd"> &quot;&quot;&quot;</span>
3334
<a id="__codelineno-0-134" name="__codelineno-0-134"></a>
3335
<a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="n">provider_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
3336
<a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="n">base_url</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
3337
<a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="n">env_var</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
3338
<a id="__codelineno-0-138" name="__codelineno-0-138"></a>
3339
<a id="__codelineno-0-139" name="__codelineno-0-139"></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">api_key</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">base_url</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
3340
<a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="kn">from</span><span class="w"> </span><span class="nn">openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">OpenAI</span>
3341
<a id="__codelineno-0-141" name="__codelineno-0-141"></a>
3342
<a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_api_key</span> <span class="o">=</span> <span class="n">api_key</span> <span class="ow">or</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">env_var</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
3343
<a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_base_url</span> <span class="o">=</span> <span class="n">base_url</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_url</span>
3344
<a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_client</span> <span class="o">=</span> <span class="n">OpenAI</span><span class="p">(</span><span class="n">api_key</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_api_key</span><span class="p">,</span> <span class="n">base_url</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_base_url</span><span class="p">)</span>
3345
<a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_last_usage</span> <span class="o">=</span> <span class="kc">None</span>
3346
<a id="__codelineno-0-146" name="__codelineno-0-146"></a>
3347
<a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="k">def</span><span class="w"> </span><span class="nf">chat</span><span class="p">(</span>
3348
<a id="__codelineno-0-148" name="__codelineno-0-148"></a> <span class="bp">self</span><span class="p">,</span>
3349
<a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="n">messages</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">dict</span><span class="p">],</span>
3350
<a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
3351
<a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="n">temperature</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.7</span><span class="p">,</span>
3352
<a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3353
<a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
3354
<a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="n">model</span> <span class="o">=</span> <span class="n">model</span> <span class="ow">or</span> <span class="s2">&quot;gpt-4o&quot;</span>
3355
<a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
3356
<a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">,</span>
3357
<a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="n">messages</span><span class="o">=</span><span class="n">messages</span><span class="p">,</span>
3358
<a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="n">max_tokens</span><span class="o">=</span><span class="n">max_tokens</span><span class="p">,</span>
3359
<a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="n">temperature</span><span class="o">=</span><span class="n">temperature</span><span class="p">,</span>
3360
<a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="p">)</span>
3361
<a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_last_usage</span> <span class="o">=</span> <span class="p">{</span>
3362
<a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="s2">&quot;input_tokens&quot;</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">usage</span><span class="p">,</span> <span class="s2">&quot;prompt_tokens&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">usage</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span>
3363
<a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="s2">&quot;output_tokens&quot;</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">usage</span><span class="p">,</span> <span class="s2">&quot;completion_tokens&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
3364
<a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">usage</span>
3365
<a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span>
3366
<a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="p">}</span>
3367
<a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">choices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">message</span><span class="o">.</span><span class="n">content</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span>
3368
<a id="__codelineno-0-168" name="__codelineno-0-168"></a>
3369
<a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="k">def</span><span class="w"> </span><span class="nf">analyze_image</span><span class="p">(</span>
3370
<a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="bp">self</span><span class="p">,</span>
3371
<a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="n">image_bytes</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span>
3372
<a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="n">prompt</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
3373
<a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
3374
<a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3375
<a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
3376
<a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="n">model</span> <span class="o">=</span> <span class="n">model</span> <span class="ow">or</span> <span class="s2">&quot;gpt-4o&quot;</span>
3377
<a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="n">b64</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64encode</span><span class="p">(</span><span class="n">image_bytes</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
3378
<a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
3379
<a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">,</span>
3380
<a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
3381
<a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="p">{</span>
3382
<a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="s2">&quot;role&quot;</span><span class="p">:</span> <span class="s2">&quot;user&quot;</span><span class="p">,</span>
3383
<a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="s2">&quot;content&quot;</span><span class="p">:</span> <span class="p">[</span>
3384
<a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;text&quot;</span><span class="p">,</span> <span class="s2">&quot;text&quot;</span><span class="p">:</span> <span class="n">prompt</span><span class="p">},</span>
3385
<a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="p">{</span>
3386
<a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;image_url&quot;</span><span class="p">,</span>
3387
<a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="s2">&quot;image_url&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;url&quot;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;data:image/jpeg;base64,</span><span class="si">{</span><span class="n">b64</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">},</span>
3388
<a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="p">},</span>
3389
<a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="p">],</span>
3390
<a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="p">}</span>
3391
<a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="p">],</span>
3392
<a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="n">max_tokens</span><span class="o">=</span><span class="n">max_tokens</span><span class="p">,</span>
3393
<a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="p">)</span>
3394
<a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_last_usage</span> <span class="o">=</span> <span class="p">{</span>
3395
<a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="s2">&quot;input_tokens&quot;</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">usage</span><span class="p">,</span> <span class="s2">&quot;prompt_tokens&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">usage</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span>
3396
<a id="__codelineno-0-196" name="__codelineno-0-196"></a> <span class="s2">&quot;output_tokens&quot;</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">usage</span><span class="p">,</span> <span class="s2">&quot;completion_tokens&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
3397
<a id="__codelineno-0-197" name="__codelineno-0-197"></a> <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">usage</span>
3398
<a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span>
3399
<a id="__codelineno-0-199" name="__codelineno-0-199"></a> <span class="p">}</span>
3400
<a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">choices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">message</span><span class="o">.</span><span class="n">content</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span>
3401
<a id="__codelineno-0-201" name="__codelineno-0-201"></a>
3402
<a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="k">def</span><span class="w"> </span><span class="nf">transcribe_audio</span><span class="p">(</span>
3403
<a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="bp">self</span><span class="p">,</span>
3404
<a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="n">audio_path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Path</span><span class="p">,</span>
3405
<a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="n">language</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3406
<a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3407
<a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
3408
<a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">provider_name</span><span class="si">}</span><span class="s2"> does not support audio transcription&quot;</span><span class="p">)</span>
3409
<a id="__codelineno-0-209" name="__codelineno-0-209"></a>
3410
<a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="k">def</span><span class="w"> </span><span class="nf">list_models</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ModelInfo</span><span class="p">]:</span>
3411
<a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="n">models</span> <span class="o">=</span> <span class="p">[]</span>
3412
<a id="__codelineno-0-212" name="__codelineno-0-212"></a> <span class="k">try</span><span class="p">:</span>
3413
<a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_client</span><span class="o">.</span><span class="n">models</span><span class="o">.</span><span class="n">list</span><span class="p">():</span>
3414
<a id="__codelineno-0-214" name="__codelineno-0-214"></a> <span class="n">mid</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">id</span>
3415
<a id="__codelineno-0-215" name="__codelineno-0-215"></a> <span class="n">caps</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;chat&quot;</span><span class="p">]</span>
3416
<a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">models</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
3417
<a id="__codelineno-0-217" name="__codelineno-0-217"></a> <span class="n">ModelInfo</span><span class="p">(</span>
3418
<a id="__codelineno-0-218" name="__codelineno-0-218"></a> <span class="nb">id</span><span class="o">=</span><span class="n">mid</span><span class="p">,</span>
3419
<a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="n">provider</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">provider_name</span><span class="p">,</span>
3420
<a id="__codelineno-0-220" name="__codelineno-0-220"></a> <span class="n">display_name</span><span class="o">=</span><span class="n">mid</span><span class="p">,</span>
3421
<a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="n">capabilities</span><span class="o">=</span><span class="n">caps</span><span class="p">,</span>
3422
<a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="p">)</span>
3423
<a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="p">)</span>
3424
<a id="__codelineno-0-224" name="__codelineno-0-224"></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>
3425
<a id="__codelineno-0-225" name="__codelineno-0-225"></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;Failed to list </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">provider_name</span><span class="si">}</span><span class="s2"> models: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
3426
<a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">models</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="n">m</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
3427
</code></pre></div></td></tr></table></div>
3428
</details>
3429
3430
3431
3432
<div class="doc doc-children">
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
</div>
3446
3447
</div>
3448
3449
</div>
3450
3451
<div class="doc doc-object doc-class">
3452
3453
3454
3455
<h3 id="video_processor.providers.base.ProviderRegistry" class="doc doc-heading">
3456
<code>ProviderRegistry</code>
3457
3458
3459
<a href="#video_processor.providers.base.ProviderRegistry" class="headerlink" title="Permanent link">&para;</a></h3>
3460
3461
3462
<div class="doc doc-contents ">
3463
3464
3465
3466
<p>Registry for provider classes. Providers register themselves with metadata.</p>
3467
3468
3469
3470
3471
3472
3473
3474
3475
<details class="mkdocstrings-source">
3476
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3477
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-65"> 65</a></span>
3478
<span class="normal"><a href="#__codelineno-0-66"> 66</a></span>
3479
<span class="normal"><a href="#__codelineno-0-67"> 67</a></span>
3480
<span class="normal"><a href="#__codelineno-0-68"> 68</a></span>
3481
<span class="normal"><a href="#__codelineno-0-69"> 69</a></span>
3482
<span class="normal"><a href="#__codelineno-0-70"> 70</a></span>
3483
<span class="normal"><a href="#__codelineno-0-71"> 71</a></span>
3484
<span class="normal"><a href="#__codelineno-0-72"> 72</a></span>
3485
<span class="normal"><a href="#__codelineno-0-73"> 73</a></span>
3486
<span class="normal"><a href="#__codelineno-0-74"> 74</a></span>
3487
<span class="normal"><a href="#__codelineno-0-75"> 75</a></span>
3488
<span class="normal"><a href="#__codelineno-0-76"> 76</a></span>
3489
<span class="normal"><a href="#__codelineno-0-77"> 77</a></span>
3490
<span class="normal"><a href="#__codelineno-0-78"> 78</a></span>
3491
<span class="normal"><a href="#__codelineno-0-79"> 79</a></span>
3492
<span class="normal"><a href="#__codelineno-0-80"> 80</a></span>
3493
<span class="normal"><a href="#__codelineno-0-81"> 81</a></span>
3494
<span class="normal"><a href="#__codelineno-0-82"> 82</a></span>
3495
<span class="normal"><a href="#__codelineno-0-83"> 83</a></span>
3496
<span class="normal"><a href="#__codelineno-0-84"> 84</a></span>
3497
<span class="normal"><a href="#__codelineno-0-85"> 85</a></span>
3498
<span class="normal"><a href="#__codelineno-0-86"> 86</a></span>
3499
<span class="normal"><a href="#__codelineno-0-87"> 87</a></span>
3500
<span class="normal"><a href="#__codelineno-0-88"> 88</a></span>
3501
<span class="normal"><a href="#__codelineno-0-89"> 89</a></span>
3502
<span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
3503
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
3504
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
3505
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
3506
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
3507
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
3508
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
3509
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
3510
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
3511
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
3512
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
3513
<span class="normal"><a href="#__codelineno-0-101">101</a></span>
3514
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
3515
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
3516
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
3517
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
3518
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
3519
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
3520
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
3521
<span class="normal"><a href="#__codelineno-0-109">109</a></span>
3522
<span class="normal"><a href="#__codelineno-0-110">110</a></span>
3523
<span class="normal"><a href="#__codelineno-0-111">111</a></span>
3524
<span class="normal"><a href="#__codelineno-0-112">112</a></span>
3525
<span class="normal"><a href="#__codelineno-0-113">113</a></span>
3526
<span class="normal"><a href="#__codelineno-0-114">114</a></span>
3527
<span class="normal"><a href="#__codelineno-0-115">115</a></span>
3528
<span class="normal"><a href="#__codelineno-0-116">116</a></span>
3529
<span class="normal"><a href="#__codelineno-0-117">117</a></span>
3530
<span class="normal"><a href="#__codelineno-0-118">118</a></span>
3531
<span class="normal"><a href="#__codelineno-0-119">119</a></span>
3532
<span class="normal"><a href="#__codelineno-0-120">120</a></span>
3533
<span class="normal"><a href="#__codelineno-0-121">121</a></span>
3534
<span class="normal"><a href="#__codelineno-0-122">122</a></span>
3535
<span class="normal"><a href="#__codelineno-0-123">123</a></span>
3536
<span class="normal"><a href="#__codelineno-0-124">124</a></span>
3537
<span class="normal"><a href="#__codelineno-0-125">125</a></span>
3538
<span class="normal"><a href="#__codelineno-0-126">126</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-65" name="__codelineno-0-65"></a><span class="k">class</span><span class="w"> </span><span class="nc">ProviderRegistry</span><span class="p">:</span>
3539
<a id="__codelineno-0-66" name="__codelineno-0-66"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Registry for provider classes. Providers register themselves with metadata.&quot;&quot;&quot;</span>
3540
<a id="__codelineno-0-67" name="__codelineno-0-67"></a>
3541
<a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="n">_providers</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Dict</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
3542
<a id="__codelineno-0-69" name="__codelineno-0-69"></a>
3543
<a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="nd">@classmethod</span>
3544
<a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="k">def</span><span class="w"> </span><span class="nf">register</span><span class="p">(</span>
3545
<a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="bp">cls</span><span class="p">,</span>
3546
<a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
3547
<a id="__codelineno-0-74" name="__codelineno-0-74"></a> <span class="n">provider_class</span><span class="p">:</span> <span class="nb">type</span><span class="p">,</span>
3548
<a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="n">env_var</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
3549
<a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="n">model_prefixes</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="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3550
<a id="__codelineno-0-77" name="__codelineno-0-77"></a> <span class="n">default_models</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3551
<a id="__codelineno-0-78" name="__codelineno-0-78"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
3552
<a id="__codelineno-0-79" name="__codelineno-0-79"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Register a provider class with its metadata.&quot;&quot;&quot;</span>
3553
<a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
3554
<a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="s2">&quot;class&quot;</span><span class="p">:</span> <span class="n">provider_class</span><span class="p">,</span>
3555
<a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="s2">&quot;env_var&quot;</span><span class="p">:</span> <span class="n">env_var</span><span class="p">,</span>
3556
<a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="s2">&quot;model_prefixes&quot;</span><span class="p">:</span> <span class="n">model_prefixes</span> <span class="ow">or</span> <span class="p">[],</span>
3557
<a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="s2">&quot;default_models&quot;</span><span class="p">:</span> <span class="n">default_models</span> <span class="ow">or</span> <span class="p">{},</span>
3558
<a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="p">}</span>
3559
<a id="__codelineno-0-86" name="__codelineno-0-86"></a>
3560
<a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="nd">@classmethod</span>
3561
<a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">type</span><span class="p">:</span>
3562
<a id="__codelineno-0-89" name="__codelineno-0-89"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return the provider class for a given name.&quot;&quot;&quot;</span>
3563
<a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">:</span>
3564
<a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unknown provider: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
3565
<a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">[</span><span class="n">name</span><span class="p">][</span><span class="s2">&quot;class&quot;</span><span class="p">]</span>
3566
<a id="__codelineno-0-93" name="__codelineno-0-93"></a>
3567
<a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="nd">@classmethod</span>
3568
<a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_by_model</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">model_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
3569
<a id="__codelineno-0-96" name="__codelineno-0-96"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return provider name for a model ID based on prefix matching.&quot;&quot;&quot;</span>
3570
<a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">info</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
3571
<a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="k">for</span> <span class="n">prefix</span> <span class="ow">in</span> <span class="n">info</span><span class="p">[</span><span class="s2">&quot;model_prefixes&quot;</span><span class="p">]:</span>
3572
<a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="k">if</span> <span class="n">model_id</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">prefix</span><span class="p">):</span>
3573
<a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="k">return</span> <span class="n">name</span>
3574
<a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="k">return</span> <span class="kc">None</span>
3575
<a id="__codelineno-0-102" name="__codelineno-0-102"></a>
3576
<a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="nd">@classmethod</span>
3577
<a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_default_models</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
3578
<a id="__codelineno-0-105" name="__codelineno-0-105"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return the default models dict for a provider.&quot;&quot;&quot;</span>
3579
<a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">:</span>
3580
<a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="k">return</span> <span class="p">{}</span>
3581
<a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">[</span><span class="n">name</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;default_models&quot;</span><span class="p">,</span> <span class="p">{})</span>
3582
<a id="__codelineno-0-109" name="__codelineno-0-109"></a>
3583
<a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="nd">@classmethod</span>
3584
<a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="k">def</span><span class="w"> </span><span class="nf">available</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
3585
<a id="__codelineno-0-112" name="__codelineno-0-112"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return names of providers whose env var is set (or have no env var requirement).&quot;&quot;&quot;</span>
3586
<a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
3587
<a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">info</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
3588
<a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="n">env_var</span> <span class="o">=</span> <span class="n">info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;env_var&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
3589
<a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">env_var</span><span class="p">:</span>
3590
<a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="c1"># Providers without an env var (e.g. ollama) need special availability checks</span>
3591
<a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
3592
<a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="k">elif</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="n">env_var</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">):</span>
3593
<a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
3594
<a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="k">return</span> <span class="n">result</span>
3595
<a id="__codelineno-0-122" name="__codelineno-0-122"></a>
3596
<a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="nd">@classmethod</span>
3597
<a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="k">def</span><span class="w"> </span><span class="nf">all_registered</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Dict</span><span class="p">]:</span>
3598
<a id="__codelineno-0-125" name="__codelineno-0-125"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return all registered providers and their metadata.&quot;&quot;&quot;</span>
3599
<a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">)</span>
3600
</code></pre></div></td></tr></table></div>
3601
</details>
3602
3603
3604
3605
<div class="doc doc-children">
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
<div class="doc doc-object doc-function">
3617
3618
3619
<h4 id="video_processor.providers.base.ProviderRegistry.all_registered" class="doc doc-heading">
3620
<code class="highlight language-python"><span class="n">all_registered</span><span class="p">()</span></code>
3621
3622
<span class="doc doc-labels">
3623
<small class="doc doc-label doc-label-classmethod"><code>classmethod</code></small>
3624
</span>
3625
3626
<a href="#video_processor.providers.base.ProviderRegistry.all_registered" class="headerlink" title="Permanent link">&para;</a></h4>
3627
3628
3629
<div class="doc doc-contents ">
3630
3631
<p>Return all registered providers and their metadata.</p>
3632
3633
3634
<details class="mkdocstrings-source">
3635
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3636
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-123">123</a></span>
3637
<span class="normal"><a href="#__codelineno-0-124">124</a></span>
3638
<span class="normal"><a href="#__codelineno-0-125">125</a></span>
3639
<span class="normal"><a href="#__codelineno-0-126">126</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-123" name="__codelineno-0-123"></a><span class="nd">@classmethod</span>
3640
<a id="__codelineno-0-124" name="__codelineno-0-124"></a><span class="k">def</span><span class="w"> </span><span class="nf">all_registered</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Dict</span><span class="p">]:</span>
3641
<a id="__codelineno-0-125" name="__codelineno-0-125"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return all registered providers and their metadata.&quot;&quot;&quot;</span>
3642
<a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">)</span>
3643
</code></pre></div></td></tr></table></div>
3644
</details>
3645
</div>
3646
3647
</div>
3648
3649
<div class="doc doc-object doc-function">
3650
3651
3652
<h4 id="video_processor.providers.base.ProviderRegistry.available" class="doc doc-heading">
3653
<code class="highlight language-python"><span class="n">available</span><span class="p">()</span></code>
3654
3655
<span class="doc doc-labels">
3656
<small class="doc doc-label doc-label-classmethod"><code>classmethod</code></small>
3657
</span>
3658
3659
<a href="#video_processor.providers.base.ProviderRegistry.available" class="headerlink" title="Permanent link">&para;</a></h4>
3660
3661
3662
<div class="doc doc-contents ">
3663
3664
<p>Return names of providers whose env var is set (or have no env var requirement).</p>
3665
3666
3667
<details class="mkdocstrings-source">
3668
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3669
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-110">110</a></span>
3670
<span class="normal"><a href="#__codelineno-0-111">111</a></span>
3671
<span class="normal"><a href="#__codelineno-0-112">112</a></span>
3672
<span class="normal"><a href="#__codelineno-0-113">113</a></span>
3673
<span class="normal"><a href="#__codelineno-0-114">114</a></span>
3674
<span class="normal"><a href="#__codelineno-0-115">115</a></span>
3675
<span class="normal"><a href="#__codelineno-0-116">116</a></span>
3676
<span class="normal"><a href="#__codelineno-0-117">117</a></span>
3677
<span class="normal"><a href="#__codelineno-0-118">118</a></span>
3678
<span class="normal"><a href="#__codelineno-0-119">119</a></span>
3679
<span class="normal"><a href="#__codelineno-0-120">120</a></span>
3680
<span class="normal"><a href="#__codelineno-0-121">121</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-110" name="__codelineno-0-110"></a><span class="nd">@classmethod</span>
3681
<a id="__codelineno-0-111" name="__codelineno-0-111"></a><span class="k">def</span><span class="w"> </span><span class="nf">available</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
3682
<a id="__codelineno-0-112" name="__codelineno-0-112"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return names of providers whose env var is set (or have no env var requirement).&quot;&quot;&quot;</span>
3683
<a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
3684
<a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">info</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
3685
<a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="n">env_var</span> <span class="o">=</span> <span class="n">info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;env_var&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
3686
<a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">env_var</span><span class="p">:</span>
3687
<a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="c1"># Providers without an env var (e.g. ollama) need special availability checks</span>
3688
<a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
3689
<a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="k">elif</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="n">env_var</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">):</span>
3690
<a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
3691
<a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="k">return</span> <span class="n">result</span>
3692
</code></pre></div></td></tr></table></div>
3693
</details>
3694
</div>
3695
3696
</div>
3697
3698
<div class="doc doc-object doc-function">
3699
3700
3701
<h4 id="video_processor.providers.base.ProviderRegistry.get" class="doc doc-heading">
3702
<code class="highlight language-python"><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span></code>
3703
3704
<span class="doc doc-labels">
3705
<small class="doc doc-label doc-label-classmethod"><code>classmethod</code></small>
3706
</span>
3707
3708
<a href="#video_processor.providers.base.ProviderRegistry.get" class="headerlink" title="Permanent link">&para;</a></h4>
3709
3710
3711
<div class="doc doc-contents ">
3712
3713
<p>Return the provider class for a given name.</p>
3714
3715
3716
<details class="mkdocstrings-source">
3717
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3718
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-87">87</a></span>
3719
<span class="normal"><a href="#__codelineno-0-88">88</a></span>
3720
<span class="normal"><a href="#__codelineno-0-89">89</a></span>
3721
<span class="normal"><a href="#__codelineno-0-90">90</a></span>
3722
<span class="normal"><a href="#__codelineno-0-91">91</a></span>
3723
<span class="normal"><a href="#__codelineno-0-92">92</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-87" name="__codelineno-0-87"></a><span class="nd">@classmethod</span>
3724
<a id="__codelineno-0-88" name="__codelineno-0-88"></a><span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">type</span><span class="p">:</span>
3725
<a id="__codelineno-0-89" name="__codelineno-0-89"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return the provider class for a given name.&quot;&quot;&quot;</span>
3726
<a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">:</span>
3727
<a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unknown provider: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
3728
<a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">[</span><span class="n">name</span><span class="p">][</span><span class="s2">&quot;class&quot;</span><span class="p">]</span>
3729
</code></pre></div></td></tr></table></div>
3730
</details>
3731
</div>
3732
3733
</div>
3734
3735
<div class="doc doc-object doc-function">
3736
3737
3738
<h4 id="video_processor.providers.base.ProviderRegistry.get_by_model" class="doc doc-heading">
3739
<code class="highlight language-python"><span class="n">get_by_model</span><span class="p">(</span><span class="n">model_id</span><span class="p">)</span></code>
3740
3741
<span class="doc doc-labels">
3742
<small class="doc doc-label doc-label-classmethod"><code>classmethod</code></small>
3743
</span>
3744
3745
<a href="#video_processor.providers.base.ProviderRegistry.get_by_model" class="headerlink" title="Permanent link">&para;</a></h4>
3746
3747
3748
<div class="doc doc-contents ">
3749
3750
<p>Return provider name for a model ID based on prefix matching.</p>
3751
3752
3753
<details class="mkdocstrings-source">
3754
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3755
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
3756
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
3757
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
3758
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
3759
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
3760
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
3761
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
3762
<span class="normal"><a href="#__codelineno-0-101">101</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-94" name="__codelineno-0-94"></a><span class="nd">@classmethod</span>
3763
<a id="__codelineno-0-95" name="__codelineno-0-95"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_by_model</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">model_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
3764
<a id="__codelineno-0-96" name="__codelineno-0-96"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return provider name for a model ID based on prefix matching.&quot;&quot;&quot;</span>
3765
<a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">info</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
3766
<a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="k">for</span> <span class="n">prefix</span> <span class="ow">in</span> <span class="n">info</span><span class="p">[</span><span class="s2">&quot;model_prefixes&quot;</span><span class="p">]:</span>
3767
<a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="k">if</span> <span class="n">model_id</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">prefix</span><span class="p">):</span>
3768
<a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="k">return</span> <span class="n">name</span>
3769
<a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="k">return</span> <span class="kc">None</span>
3770
</code></pre></div></td></tr></table></div>
3771
</details>
3772
</div>
3773
3774
</div>
3775
3776
<div class="doc doc-object doc-function">
3777
3778
3779
<h4 id="video_processor.providers.base.ProviderRegistry.get_default_models" class="doc doc-heading">
3780
<code class="highlight language-python"><span class="n">get_default_models</span><span class="p">(</span><span class="n">name</span><span class="p">)</span></code>
3781
3782
<span class="doc doc-labels">
3783
<small class="doc doc-label doc-label-classmethod"><code>classmethod</code></small>
3784
</span>
3785
3786
<a href="#video_processor.providers.base.ProviderRegistry.get_default_models" class="headerlink" title="Permanent link">&para;</a></h4>
3787
3788
3789
<div class="doc doc-contents ">
3790
3791
<p>Return the default models dict for a provider.</p>
3792
3793
3794
<details class="mkdocstrings-source">
3795
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3796
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-103">103</a></span>
3797
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
3798
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
3799
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
3800
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
3801
<span class="normal"><a href="#__codelineno-0-108">108</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-103" name="__codelineno-0-103"></a><span class="nd">@classmethod</span>
3802
<a id="__codelineno-0-104" name="__codelineno-0-104"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_default_models</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
3803
<a id="__codelineno-0-105" name="__codelineno-0-105"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return the default models dict for a provider.&quot;&quot;&quot;</span>
3804
<a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">:</span>
3805
<a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="k">return</span> <span class="p">{}</span>
3806
<a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">[</span><span class="n">name</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;default_models&quot;</span><span class="p">,</span> <span class="p">{})</span>
3807
</code></pre></div></td></tr></table></div>
3808
</details>
3809
</div>
3810
3811
</div>
3812
3813
<div class="doc doc-object doc-function">
3814
3815
3816
<h4 id="video_processor.providers.base.ProviderRegistry.register" class="doc doc-heading">
3817
<code class="highlight language-python"><span class="n">register</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">provider_class</span><span class="p">,</span> <span class="n">env_var</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">model_prefixes</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">default_models</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code>
3818
3819
<span class="doc doc-labels">
3820
<small class="doc doc-label doc-label-classmethod"><code>classmethod</code></small>
3821
</span>
3822
3823
<a href="#video_processor.providers.base.ProviderRegistry.register" class="headerlink" title="Permanent link">&para;</a></h4>
3824
3825
3826
<div class="doc doc-contents ">
3827
3828
<p>Register a provider class with its metadata.</p>
3829
3830
3831
<details class="mkdocstrings-source">
3832
<summary>Source code in <code>video_processor/providers/base.py</code></summary>
3833
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-70">70</a></span>
3834
<span class="normal"><a href="#__codelineno-0-71">71</a></span>
3835
<span class="normal"><a href="#__codelineno-0-72">72</a></span>
3836
<span class="normal"><a href="#__codelineno-0-73">73</a></span>
3837
<span class="normal"><a href="#__codelineno-0-74">74</a></span>
3838
<span class="normal"><a href="#__codelineno-0-75">75</a></span>
3839
<span class="normal"><a href="#__codelineno-0-76">76</a></span>
3840
<span class="normal"><a href="#__codelineno-0-77">77</a></span>
3841
<span class="normal"><a href="#__codelineno-0-78">78</a></span>
3842
<span class="normal"><a href="#__codelineno-0-79">79</a></span>
3843
<span class="normal"><a href="#__codelineno-0-80">80</a></span>
3844
<span class="normal"><a href="#__codelineno-0-81">81</a></span>
3845
<span class="normal"><a href="#__codelineno-0-82">82</a></span>
3846
<span class="normal"><a href="#__codelineno-0-83">83</a></span>
3847
<span class="normal"><a href="#__codelineno-0-84">84</a></span>
3848
<span class="normal"><a href="#__codelineno-0-85">85</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-70" name="__codelineno-0-70"></a><span class="nd">@classmethod</span>
3849
<a id="__codelineno-0-71" name="__codelineno-0-71"></a><span class="k">def</span><span class="w"> </span><span class="nf">register</span><span class="p">(</span>
3850
<a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="bp">cls</span><span class="p">,</span>
3851
<a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
3852
<a id="__codelineno-0-74" name="__codelineno-0-74"></a> <span class="n">provider_class</span><span class="p">:</span> <span class="nb">type</span><span class="p">,</span>
3853
<a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="n">env_var</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
3854
<a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="n">model_prefixes</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="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3855
<a id="__codelineno-0-77" name="__codelineno-0-77"></a> <span class="n">default_models</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3856
<a id="__codelineno-0-78" name="__codelineno-0-78"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
3857
<a id="__codelineno-0-79" name="__codelineno-0-79"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Register a provider class with its metadata.&quot;&quot;&quot;</span>
3858
<a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="bp">cls</span><span class="o">.</span><span class="n">_providers</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
3859
<a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="s2">&quot;class&quot;</span><span class="p">:</span> <span class="n">provider_class</span><span class="p">,</span>
3860
<a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="s2">&quot;env_var&quot;</span><span class="p">:</span> <span class="n">env_var</span><span class="p">,</span>
3861
<a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="s2">&quot;model_prefixes&quot;</span><span class="p">:</span> <span class="n">model_prefixes</span> <span class="ow">or</span> <span class="p">[],</span>
3862
<a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="s2">&quot;default_models&quot;</span><span class="p">:</span> <span class="n">default_models</span> <span class="ow">or</span> <span class="p">{},</span>
3863
<a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="p">}</span>
3864
</code></pre></div></td></tr></table></div>
3865
</details>
3866
</div>
3867
3868
</div>
3869
3870
3871
3872
</div>
3873
3874
</div>
3875
3876
</div>
3877
3878
3879
3880
3881
</div>
3882
3883
</div>
3884
3885
</div>
3886
3887
<div class="doc doc-object doc-module">
3888
3889
3890
3891
<h2 id="video_processor.providers.manager" class="doc doc-heading">
3892
<code>video_processor.providers.manager</code>
3893
3894
3895
<a href="#video_processor.providers.manager" class="headerlink" title="Permanent link">&para;</a></h2>
3896
3897
<div class="doc doc-contents first">
3898
3899
<p>ProviderManager - unified interface for routing API calls to the best available provider.</p>
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
<div class="doc doc-children">
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
<div class="doc doc-object doc-class">
3921
3922
3923
3924
<h3 id="video_processor.providers.manager.ProviderManager" class="doc doc-heading">
3925
<code>ProviderManager</code>
3926
3927
3928
<a href="#video_processor.providers.manager.ProviderManager" class="headerlink" title="Permanent link">&para;</a></h3>
3929
3930
3931
<div class="doc doc-contents ">
3932
3933
3934
3935
<p>Routes API calls to the best available provider/model.</p>
3936
<p>Supports explicit model selection or auto-routing based on
3937
discovered available models.</p>
3938
3939
3940
3941
3942
3943
3944
3945
3946
<details class="mkdocstrings-source">
3947
<summary>Source code in <code>video_processor/providers/manager.py</code></summary>
3948
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-52"> 52</a></span>
3949
<span class="normal"><a href="#__codelineno-0-53"> 53</a></span>
3950
<span class="normal"><a href="#__codelineno-0-54"> 54</a></span>
3951
<span class="normal"><a href="#__codelineno-0-55"> 55</a></span>
3952
<span class="normal"><a href="#__codelineno-0-56"> 56</a></span>
3953
<span class="normal"><a href="#__codelineno-0-57"> 57</a></span>
3954
<span class="normal"><a href="#__codelineno-0-58"> 58</a></span>
3955
<span class="normal"><a href="#__codelineno-0-59"> 59</a></span>
3956
<span class="normal"><a href="#__codelineno-0-60"> 60</a></span>
3957
<span class="normal"><a href="#__codelineno-0-61"> 61</a></span>
3958
<span class="normal"><a href="#__codelineno-0-62"> 62</a></span>
3959
<span class="normal"><a href="#__codelineno-0-63"> 63</a></span>
3960
<span class="normal"><a href="#__codelineno-0-64"> 64</a></span>
3961
<span class="normal"><a href="#__codelineno-0-65"> 65</a></span>
3962
<span class="normal"><a href="#__codelineno-0-66"> 66</a></span>
3963
<span class="normal"><a href="#__codelineno-0-67"> 67</a></span>
3964
<span class="normal"><a href="#__codelineno-0-68"> 68</a></span>
3965
<span class="normal"><a href="#__codelineno-0-69"> 69</a></span>
3966
<span class="normal"><a href="#__codelineno-0-70"> 70</a></span>
3967
<span class="normal"><a href="#__codelineno-0-71"> 71</a></span>
3968
<span class="normal"><a href="#__codelineno-0-72"> 72</a></span>
3969
<span class="normal"><a href="#__codelineno-0-73"> 73</a></span>
3970
<span class="normal"><a href="#__codelineno-0-74"> 74</a></span>
3971
<span class="normal"><a href="#__codelineno-0-75"> 75</a></span>
3972
<span class="normal"><a href="#__codelineno-0-76"> 76</a></span>
3973
<span class="normal"><a href="#__codelineno-0-77"> 77</a></span>
3974
<span class="normal"><a href="#__codelineno-0-78"> 78</a></span>
3975
<span class="normal"><a href="#__codelineno-0-79"> 79</a></span>
3976
<span class="normal"><a href="#__codelineno-0-80"> 80</a></span>
3977
<span class="normal"><a href="#__codelineno-0-81"> 81</a></span>
3978
<span class="normal"><a href="#__codelineno-0-82"> 82</a></span>
3979
<span class="normal"><a href="#__codelineno-0-83"> 83</a></span>
3980
<span class="normal"><a href="#__codelineno-0-84"> 84</a></span>
3981
<span class="normal"><a href="#__codelineno-0-85"> 85</a></span>
3982
<span class="normal"><a href="#__codelineno-0-86"> 86</a></span>
3983
<span class="normal"><a href="#__codelineno-0-87"> 87</a></span>
3984
<span class="normal"><a href="#__codelineno-0-88"> 88</a></span>
3985
<span class="normal"><a href="#__codelineno-0-89"> 89</a></span>
3986
<span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
3987
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
3988
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
3989
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
3990
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
3991
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
3992
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
3993
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
3994
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
3995
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
3996
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
3997
<span class="normal"><a href="#__codelineno-0-101">101</a></span>
3998
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
3999
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
4000
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
4001
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
4002
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
4003
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
4004
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
4005
<span class="normal"><a href="#__codelineno-0-109">109</a></span>
4006
<span class="normal"><a href="#__codelineno-0-110">110</a></span>
4007
<span class="normal"><a href="#__codelineno-0-111">111</a></span>
4008
<span class="normal"><a href="#__codelineno-0-112">112</a></span>
4009
<span class="normal"><a href="#__codelineno-0-113">113</a></span>
4010
<span class="normal"><a href="#__codelineno-0-114">114</a></span>
4011
<span class="normal"><a href="#__codelineno-0-115">115</a></span>
4012
<span class="normal"><a href="#__codelineno-0-116">116</a></span>
4013
<span class="normal"><a href="#__codelineno-0-117">117</a></span>
4014
<span class="normal"><a href="#__codelineno-0-118">118</a></span>
4015
<span class="normal"><a href="#__codelineno-0-119">119</a></span>
4016
<span class="normal"><a href="#__codelineno-0-120">120</a></span>
4017
<span class="normal"><a href="#__codelineno-0-121">121</a></span>
4018
<span class="normal"><a href="#__codelineno-0-122">122</a></span>
4019
<span class="normal"><a href="#__codelineno-0-123">123</a></span>
4020
<span class="normal"><a href="#__codelineno-0-124">124</a></span>
4021
<span class="normal"><a href="#__codelineno-0-125">125</a></span>
4022
<span class="normal"><a href="#__codelineno-0-126">126</a></span>
4023
<span class="normal"><a href="#__codelineno-0-127">127</a></span>
4024
<span class="normal"><a href="#__codelineno-0-128">128</a></span>
4025
<span class="normal"><a href="#__codelineno-0-129">129</a></span>
4026
<span class="normal"><a href="#__codelineno-0-130">130</a></span>
4027
<span class="normal"><a href="#__codelineno-0-131">131</a></span>
4028
<span class="normal"><a href="#__codelineno-0-132">132</a></span>
4029
<span class="normal"><a href="#__codelineno-0-133">133</a></span>
4030
<span class="normal"><a href="#__codelineno-0-134">134</a></span>
4031
<span class="normal"><a href="#__codelineno-0-135">135</a></span>
4032
<span class="normal"><a href="#__codelineno-0-136">136</a></span>
4033
<span class="normal"><a href="#__codelineno-0-137">137</a></span>
4034
<span class="normal"><a href="#__codelineno-0-138">138</a></span>
4035
<span class="normal"><a href="#__codelineno-0-139">139</a></span>
4036
<span class="normal"><a href="#__codelineno-0-140">140</a></span>
4037
<span class="normal"><a href="#__codelineno-0-141">141</a></span>
4038
<span class="normal"><a href="#__codelineno-0-142">142</a></span>
4039
<span class="normal"><a href="#__codelineno-0-143">143</a></span>
4040
<span class="normal"><a href="#__codelineno-0-144">144</a></span>
4041
<span class="normal"><a href="#__codelineno-0-145">145</a></span>
4042
<span class="normal"><a href="#__codelineno-0-146">146</a></span>
4043
<span class="normal"><a href="#__codelineno-0-147">147</a></span>
4044
<span class="normal"><a href="#__codelineno-0-148">148</a></span>
4045
<span class="normal"><a href="#__codelineno-0-149">149</a></span>
4046
<span class="normal"><a href="#__codelineno-0-150">150</a></span>
4047
<span class="normal"><a href="#__codelineno-0-151">151</a></span>
4048
<span class="normal"><a href="#__codelineno-0-152">152</a></span>
4049
<span class="normal"><a href="#__codelineno-0-153">153</a></span>
4050
<span class="normal"><a href="#__codelineno-0-154">154</a></span>
4051
<span class="normal"><a href="#__codelineno-0-155">155</a></span>
4052
<span class="normal"><a href="#__codelineno-0-156">156</a></span>
4053
<span class="normal"><a href="#__codelineno-0-157">157</a></span>
4054
<span class="normal"><a href="#__codelineno-0-158">158</a></span>
4055
<span class="normal"><a href="#__codelineno-0-159">159</a></span>
4056
<span class="normal"><a href="#__codelineno-0-160">160</a></span>
4057
<span class="normal"><a href="#__codelineno-0-161">161</a></span>
4058
<span class="normal"><a href="#__codelineno-0-162">162</a></span>
4059
<span class="normal"><a href="#__codelineno-0-163">163</a></span>
4060
<span class="normal"><a href="#__codelineno-0-164">164</a></span>
4061
<span class="normal"><a href="#__codelineno-0-165">165</a></span>
4062
<span class="normal"><a href="#__codelineno-0-166">166</a></span>
4063
<span class="normal"><a href="#__codelineno-0-167">167</a></span>
4064
<span class="normal"><a href="#__codelineno-0-168">168</a></span>
4065
<span class="normal"><a href="#__codelineno-0-169">169</a></span>
4066
<span class="normal"><a href="#__codelineno-0-170">170</a></span>
4067
<span class="normal"><a href="#__codelineno-0-171">171</a></span>
4068
<span class="normal"><a href="#__codelineno-0-172">172</a></span>
4069
<span class="normal"><a href="#__codelineno-0-173">173</a></span>
4070
<span class="normal"><a href="#__codelineno-0-174">174</a></span>
4071
<span class="normal"><a href="#__codelineno-0-175">175</a></span>
4072
<span class="normal"><a href="#__codelineno-0-176">176</a></span>
4073
<span class="normal"><a href="#__codelineno-0-177">177</a></span>
4074
<span class="normal"><a href="#__codelineno-0-178">178</a></span>
4075
<span class="normal"><a href="#__codelineno-0-179">179</a></span>
4076
<span class="normal"><a href="#__codelineno-0-180">180</a></span>
4077
<span class="normal"><a href="#__codelineno-0-181">181</a></span>
4078
<span class="normal"><a href="#__codelineno-0-182">182</a></span>
4079
<span class="normal"><a href="#__codelineno-0-183">183</a></span>
4080
<span class="normal"><a href="#__codelineno-0-184">184</a></span>
4081
<span class="normal"><a href="#__codelineno-0-185">185</a></span>
4082
<span class="normal"><a href="#__codelineno-0-186">186</a></span>
4083
<span class="normal"><a href="#__codelineno-0-187">187</a></span>
4084
<span class="normal"><a href="#__codelineno-0-188">188</a></span>
4085
<span class="normal"><a href="#__codelineno-0-189">189</a></span>
4086
<span class="normal"><a href="#__codelineno-0-190">190</a></span>
4087
<span class="normal"><a href="#__codelineno-0-191">191</a></span>
4088
<span class="normal"><a href="#__codelineno-0-192">192</a></span>
4089
<span class="normal"><a href="#__codelineno-0-193">193</a></span>
4090
<span class="normal"><a href="#__codelineno-0-194">194</a></span>
4091
<span class="normal"><a href="#__codelineno-0-195">195</a></span>
4092
<span class="normal"><a href="#__codelineno-0-196">196</a></span>
4093
<span class="normal"><a href="#__codelineno-0-197">197</a></span>
4094
<span class="normal"><a href="#__codelineno-0-198">198</a></span>
4095
<span class="normal"><a href="#__codelineno-0-199">199</a></span>
4096
<span class="normal"><a href="#__codelineno-0-200">200</a></span>
4097
<span class="normal"><a href="#__codelineno-0-201">201</a></span>
4098
<span class="normal"><a href="#__codelineno-0-202">202</a></span>
4099
<span class="normal"><a href="#__codelineno-0-203">203</a></span>
4100
<span class="normal"><a href="#__codelineno-0-204">204</a></span>
4101
<span class="normal"><a href="#__codelineno-0-205">205</a></span>
4102
<span class="normal"><a href="#__codelineno-0-206">206</a></span>
4103
<span class="normal"><a href="#__codelineno-0-207">207</a></span>
4104
<span class="normal"><a href="#__codelineno-0-208">208</a></span>
4105
<span class="normal"><a href="#__codelineno-0-209">209</a></span>
4106
<span class="normal"><a href="#__codelineno-0-210">210</a></span>
4107
<span class="normal"><a href="#__codelineno-0-211">211</a></span>
4108
<span class="normal"><a href="#__codelineno-0-212">212</a></span>
4109
<span class="normal"><a href="#__codelineno-0-213">213</a></span>
4110
<span class="normal"><a href="#__codelineno-0-214">214</a></span>
4111
<span class="normal"><a href="#__codelineno-0-215">215</a></span>
4112
<span class="normal"><a href="#__codelineno-0-216">216</a></span>
4113
<span class="normal"><a href="#__codelineno-0-217">217</a></span>
4114
<span class="normal"><a href="#__codelineno-0-218">218</a></span>
4115
<span class="normal"><a href="#__codelineno-0-219">219</a></span>
4116
<span class="normal"><a href="#__codelineno-0-220">220</a></span>
4117
<span class="normal"><a href="#__codelineno-0-221">221</a></span>
4118
<span class="normal"><a href="#__codelineno-0-222">222</a></span>
4119
<span class="normal"><a href="#__codelineno-0-223">223</a></span>
4120
<span class="normal"><a href="#__codelineno-0-224">224</a></span>
4121
<span class="normal"><a href="#__codelineno-0-225">225</a></span>
4122
<span class="normal"><a href="#__codelineno-0-226">226</a></span>
4123
<span class="normal"><a href="#__codelineno-0-227">227</a></span>
4124
<span class="normal"><a href="#__codelineno-0-228">228</a></span>
4125
<span class="normal"><a href="#__codelineno-0-229">229</a></span>
4126
<span class="normal"><a href="#__codelineno-0-230">230</a></span>
4127
<span class="normal"><a href="#__codelineno-0-231">231</a></span>
4128
<span class="normal"><a href="#__codelineno-0-232">232</a></span>
4129
<span class="normal"><a href="#__codelineno-0-233">233</a></span>
4130
<span class="normal"><a href="#__codelineno-0-234">234</a></span>
4131
<span class="normal"><a href="#__codelineno-0-235">235</a></span>
4132
<span class="normal"><a href="#__codelineno-0-236">236</a></span>
4133
<span class="normal"><a href="#__codelineno-0-237">237</a></span>
4134
<span class="normal"><a href="#__codelineno-0-238">238</a></span>
4135
<span class="normal"><a href="#__codelineno-0-239">239</a></span>
4136
<span class="normal"><a href="#__codelineno-0-240">240</a></span>
4137
<span class="normal"><a href="#__codelineno-0-241">241</a></span>
4138
<span class="normal"><a href="#__codelineno-0-242">242</a></span>
4139
<span class="normal"><a href="#__codelineno-0-243">243</a></span>
4140
<span class="normal"><a href="#__codelineno-0-244">244</a></span>
4141
<span class="normal"><a href="#__codelineno-0-245">245</a></span>
4142
<span class="normal"><a href="#__codelineno-0-246">246</a></span>
4143
<span class="normal"><a href="#__codelineno-0-247">247</a></span>
4144
<span class="normal"><a href="#__codelineno-0-248">248</a></span>
4145
<span class="normal"><a href="#__codelineno-0-249">249</a></span>
4146
<span class="normal"><a href="#__codelineno-0-250">250</a></span>
4147
<span class="normal"><a href="#__codelineno-0-251">251</a></span>
4148
<span class="normal"><a href="#__codelineno-0-252">252</a></span>
4149
<span class="normal"><a href="#__codelineno-0-253">253</a></span>
4150
<span class="normal"><a href="#__codelineno-0-254">254</a></span>
4151
<span class="normal"><a href="#__codelineno-0-255">255</a></span>
4152
<span class="normal"><a href="#__codelineno-0-256">256</a></span>
4153
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
4154
<span class="normal"><a href="#__codelineno-0-258">258</a></span>
4155
<span class="normal"><a href="#__codelineno-0-259">259</a></span>
4156
<span class="normal"><a href="#__codelineno-0-260">260</a></span>
4157
<span class="normal"><a href="#__codelineno-0-261">261</a></span>
4158
<span class="normal"><a href="#__codelineno-0-262">262</a></span>
4159
<span class="normal"><a href="#__codelineno-0-263">263</a></span>
4160
<span class="normal"><a href="#__codelineno-0-264">264</a></span>
4161
<span class="normal"><a href="#__codelineno-0-265">265</a></span>
4162
<span class="normal"><a href="#__codelineno-0-266">266</a></span>
4163
<span class="normal"><a href="#__codelineno-0-267">267</a></span>
4164
<span class="normal"><a href="#__codelineno-0-268">268</a></span>
4165
<span class="normal"><a href="#__codelineno-0-269">269</a></span>
4166
<span class="normal"><a href="#__codelineno-0-270">270</a></span>
4167
<span class="normal"><a href="#__codelineno-0-271">271</a></span>
4168
<span class="normal"><a href="#__codelineno-0-272">272</a></span>
4169
<span class="normal"><a href="#__codelineno-0-273">273</a></span>
4170
<span class="normal"><a href="#__codelineno-0-274">274</a></span>
4171
<span class="normal"><a href="#__codelineno-0-275">275</a></span>
4172
<span class="normal"><a href="#__codelineno-0-276">276</a></span>
4173
<span class="normal"><a href="#__codelineno-0-277">277</a></span>
4174
<span class="normal"><a href="#__codelineno-0-278">278</a></span>
4175
<span class="normal"><a href="#__codelineno-0-279">279</a></span>
4176
<span class="normal"><a href="#__codelineno-0-280">280</a></span>
4177
<span class="normal"><a href="#__codelineno-0-281">281</a></span>
4178
<span class="normal"><a href="#__codelineno-0-282">282</a></span>
4179
<span class="normal"><a href="#__codelineno-0-283">283</a></span>
4180
<span class="normal"><a href="#__codelineno-0-284">284</a></span>
4181
<span class="normal"><a href="#__codelineno-0-285">285</a></span>
4182
<span class="normal"><a href="#__codelineno-0-286">286</a></span>
4183
<span class="normal"><a href="#__codelineno-0-287">287</a></span>
4184
<span class="normal"><a href="#__codelineno-0-288">288</a></span>
4185
<span class="normal"><a href="#__codelineno-0-289">289</a></span>
4186
<span class="normal"><a href="#__codelineno-0-290">290</a></span>
4187
<span class="normal"><a href="#__codelineno-0-291">291</a></span>
4188
<span class="normal"><a href="#__codelineno-0-292">292</a></span>
4189
<span class="normal"><a href="#__codelineno-0-293">293</a></span>
4190
<span class="normal"><a href="#__codelineno-0-294">294</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-52" name="__codelineno-0-52"></a><span class="k">class</span><span class="w"> </span><span class="nc">ProviderManager</span><span class="p">:</span>
4191
<a id="__codelineno-0-53" name="__codelineno-0-53"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4192
<a id="__codelineno-0-54" name="__codelineno-0-54"></a><span class="sd"> Routes API calls to the best available provider/model.</span>
4193
<a id="__codelineno-0-55" name="__codelineno-0-55"></a>
4194
<a id="__codelineno-0-56" name="__codelineno-0-56"></a><span class="sd"> Supports explicit model selection or auto-routing based on</span>
4195
<a id="__codelineno-0-57" name="__codelineno-0-57"></a><span class="sd"> discovered available models.</span>
4196
<a id="__codelineno-0-58" name="__codelineno-0-58"></a><span class="sd"> &quot;&quot;&quot;</span>
4197
<a id="__codelineno-0-59" name="__codelineno-0-59"></a>
4198
<a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
4199
<a id="__codelineno-0-61" name="__codelineno-0-61"></a> <span class="bp">self</span><span class="p">,</span>
4200
<a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="n">vision_model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4201
<a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="n">chat_model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4202
<a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="n">transcription_model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4203
<a id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="n">provider</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4204
<a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="n">auto</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
4205
<a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="p">):</span>
4206
<a id="__codelineno-0-68" name="__codelineno-0-68"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4207
<a id="__codelineno-0-69" name="__codelineno-0-69"></a><span class="sd"> Initialize the ProviderManager.</span>
4208
<a id="__codelineno-0-70" name="__codelineno-0-70"></a>
4209
<a id="__codelineno-0-71" name="__codelineno-0-71"></a><span class="sd"> Parameters</span>
4210
<a id="__codelineno-0-72" name="__codelineno-0-72"></a><span class="sd"> ----------</span>
4211
<a id="__codelineno-0-73" name="__codelineno-0-73"></a><span class="sd"> vision_model : override model for vision tasks (e.g. &#39;gpt-4o&#39;)</span>
4212
<a id="__codelineno-0-74" name="__codelineno-0-74"></a><span class="sd"> chat_model : override model for chat/LLM tasks</span>
4213
<a id="__codelineno-0-75" name="__codelineno-0-75"></a><span class="sd"> transcription_model : override model for transcription</span>
4214
<a id="__codelineno-0-76" name="__codelineno-0-76"></a><span class="sd"> provider : force all tasks to a single provider (&#39;openai&#39;, &#39;anthropic&#39;, &#39;gemini&#39;)</span>
4215
<a id="__codelineno-0-77" name="__codelineno-0-77"></a><span class="sd"> auto : if True and no model specified, pick the best available</span>
4216
<a id="__codelineno-0-78" name="__codelineno-0-78"></a><span class="sd"> &quot;&quot;&quot;</span>
4217
<a id="__codelineno-0-79" name="__codelineno-0-79"></a> <span class="n">_ensure_providers_registered</span><span class="p">()</span>
4218
<a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="bp">self</span><span class="o">.</span><span class="n">auto</span> <span class="o">=</span> <span class="n">auto</span>
4219
<a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_providers</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">BaseProvider</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
4220
<a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_available_models</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="n">ModelInfo</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
4221
<a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="bp">self</span><span class="o">.</span><span class="n">usage</span> <span class="o">=</span> <span class="n">UsageTracker</span><span class="p">()</span>
4222
<a id="__codelineno-0-84" name="__codelineno-0-84"></a>
4223
<a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="c1"># If a single provider is forced, apply it</span>
4224
<a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="k">if</span> <span class="n">provider</span><span class="p">:</span>
4225
<a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="bp">self</span><span class="o">.</span><span class="n">vision_model</span> <span class="o">=</span> <span class="n">vision_model</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default_for_provider</span><span class="p">(</span><span class="n">provider</span><span class="p">,</span> <span class="s2">&quot;vision&quot;</span><span class="p">)</span>
4226
<a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="bp">self</span><span class="o">.</span><span class="n">chat_model</span> <span class="o">=</span> <span class="n">chat_model</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default_for_provider</span><span class="p">(</span><span class="n">provider</span><span class="p">,</span> <span class="s2">&quot;chat&quot;</span><span class="p">)</span>
4227
<a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span> <span class="o">=</span> <span class="n">transcription_model</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default_for_provider</span><span class="p">(</span>
4228
<a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="n">provider</span><span class="p">,</span> <span class="s2">&quot;audio&quot;</span>
4229
<a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="p">)</span>
4230
<a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="k">else</span><span class="p">:</span>
4231
<a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="bp">self</span><span class="o">.</span><span class="n">vision_model</span> <span class="o">=</span> <span class="n">vision_model</span>
4232
<a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="bp">self</span><span class="o">.</span><span class="n">chat_model</span> <span class="o">=</span> <span class="n">chat_model</span>
4233
<a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span> <span class="o">=</span> <span class="n">transcription_model</span>
4234
<a id="__codelineno-0-96" name="__codelineno-0-96"></a>
4235
<a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_forced_provider</span> <span class="o">=</span> <span class="n">provider</span>
4236
<a id="__codelineno-0-98" name="__codelineno-0-98"></a>
4237
<a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="nd">@staticmethod</span>
4238
<a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_default_for_provider</span><span class="p">(</span><span class="n">provider</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">capability</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
4239
<a id="__codelineno-0-101" name="__codelineno-0-101"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return the default model for a provider/capability combo.&quot;&quot;&quot;</span>
4240
<a id="__codelineno-0-102" name="__codelineno-0-102"></a> <span class="n">defaults</span> <span class="o">=</span> <span class="n">ProviderRegistry</span><span class="o">.</span><span class="n">get_default_models</span><span class="p">(</span><span class="n">provider</span><span class="p">)</span>
4241
<a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="k">if</span> <span class="n">defaults</span><span class="p">:</span>
4242
<a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="k">return</span> <span class="n">defaults</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">capability</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
4243
<a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="c1"># Fallback for unregistered providers</span>
4244
<a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="k">return</span> <span class="s2">&quot;&quot;</span>
4245
<a id="__codelineno-0-107" name="__codelineno-0-107"></a>
4246
<a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_get_provider</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">provider_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">BaseProvider</span><span class="p">:</span>
4247
<a id="__codelineno-0-109" name="__codelineno-0-109"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Lazily initialize and cache a provider instance.&quot;&quot;&quot;</span>
4248
<a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="k">if</span> <span class="n">provider_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_providers</span><span class="p">:</span>
4249
<a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="n">_ensure_providers_registered</span><span class="p">()</span>
4250
<a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="n">provider_class</span> <span class="o">=</span> <span class="n">ProviderRegistry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">provider_name</span><span class="p">)</span>
4251
<a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_providers</span><span class="p">[</span><span class="n">provider_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">provider_class</span><span class="p">()</span>
4252
<a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_providers</span><span class="p">[</span><span class="n">provider_name</span><span class="p">]</span>
4253
<a id="__codelineno-0-115" name="__codelineno-0-115"></a>
4254
<a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_provider_for_model</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">model_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
4255
<a id="__codelineno-0-117" name="__codelineno-0-117"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Infer the provider from a model id.&quot;&quot;&quot;</span>
4256
<a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="n">_ensure_providers_registered</span><span class="p">()</span>
4257
<a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="c1"># Check registry prefix matching first</span>
4258
<a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="n">provider_name</span> <span class="o">=</span> <span class="n">ProviderRegistry</span><span class="o">.</span><span class="n">get_by_model</span><span class="p">(</span><span class="n">model_id</span><span class="p">)</span>
4259
<a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="k">if</span> <span class="n">provider_name</span><span class="p">:</span>
4260
<a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="k">return</span> <span class="n">provider_name</span>
4261
<a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="c1"># Try discovery (exact match, then prefix match for ollama name:tag format)</span>
4262
<a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="n">models</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_available_models</span><span class="p">()</span>
4263
<a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">models</span><span class="p">:</span>
4264
<a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="k">if</span> <span class="n">m</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="n">model_id</span><span class="p">:</span>
4265
<a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="k">return</span> <span class="n">m</span><span class="o">.</span><span class="n">provider</span>
4266
<a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">models</span><span class="p">:</span>
4267
<a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="k">if</span> <span class="n">m</span><span class="o">.</span><span class="n">id</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">model_id</span> <span class="o">+</span> <span class="s2">&quot;:&quot;</span><span class="p">):</span>
4268
<a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="k">return</span> <span class="n">m</span><span class="o">.</span><span class="n">provider</span>
4269
<a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Cannot determine provider for model: </span><span class="si">{</span><span class="n">model_id</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4270
<a id="__codelineno-0-132" name="__codelineno-0-132"></a>
4271
<a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_get_available_models</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ModelInfo</span><span class="p">]:</span>
4272
<a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_available_models</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
4273
<a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_available_models</span> <span class="o">=</span> <span class="n">discover_available_models</span><span class="p">()</span>
4274
<a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_available_models</span>
4275
<a id="__codelineno-0-137" name="__codelineno-0-137"></a>
4276
<a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_resolve_model</span><span class="p">(</span>
4277
<a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="bp">self</span><span class="p">,</span> <span class="n">explicit</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">capability</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">preferences</span><span class="p">:</span> <span class="nb">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>
4278
<a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="p">)</span> <span class="o">-&gt;</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>
4279
<a id="__codelineno-0-141" name="__codelineno-0-141"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4280
<a id="__codelineno-0-142" name="__codelineno-0-142"></a><span class="sd"> Resolve which (provider, model) to use for a capability.</span>
4281
<a id="__codelineno-0-143" name="__codelineno-0-143"></a>
4282
<a id="__codelineno-0-144" name="__codelineno-0-144"></a><span class="sd"> Returns (provider_name, model_id).</span>
4283
<a id="__codelineno-0-145" name="__codelineno-0-145"></a><span class="sd"> &quot;&quot;&quot;</span>
4284
<a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="k">if</span> <span class="n">explicit</span><span class="p">:</span>
4285
<a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="n">prov</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_provider_for_model</span><span class="p">(</span><span class="n">explicit</span><span class="p">)</span>
4286
<a id="__codelineno-0-148" name="__codelineno-0-148"></a> <span class="k">return</span> <span class="n">prov</span><span class="p">,</span> <span class="n">explicit</span>
4287
<a id="__codelineno-0-149" name="__codelineno-0-149"></a>
4288
<a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">auto</span><span class="p">:</span>
4289
<a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="c1"># Try preference order, picking the first provider that has an API key</span>
4290
<a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="k">for</span> <span class="n">prov</span><span class="p">,</span> <span class="n">model</span> <span class="ow">in</span> <span class="n">preferences</span><span class="p">:</span>
4291
<a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="k">try</span><span class="p">:</span>
4292
<a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_get_provider</span><span class="p">(</span><span class="n">prov</span><span class="p">)</span>
4293
<a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="k">return</span> <span class="n">prov</span><span class="p">,</span> <span class="n">model</span>
4294
<a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">ImportError</span><span class="p">):</span>
4295
<a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="k">continue</span>
4296
<a id="__codelineno-0-158" name="__codelineno-0-158"></a>
4297
<a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="c1"># Fallback: try Ollama if available (no API key needed)</span>
4298
<a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="k">try</span><span class="p">:</span>
4299
<a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.providers.ollama_provider</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaProvider</span>
4300
<a id="__codelineno-0-162" name="__codelineno-0-162"></a>
4301
<a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="k">if</span> <span class="n">OllamaProvider</span><span class="o">.</span><span class="n">is_available</span><span class="p">():</span>
4302
<a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="n">provider</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_provider</span><span class="p">(</span><span class="s2">&quot;ollama&quot;</span><span class="p">)</span>
4303
<a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="n">models</span> <span class="o">=</span> <span class="n">provider</span><span class="o">.</span><span class="n">list_models</span><span class="p">()</span>
4304
<a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">models</span><span class="p">:</span>
4305
<a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="k">if</span> <span class="n">capability</span> <span class="ow">in</span> <span class="n">m</span><span class="o">.</span><span class="n">capabilities</span><span class="p">:</span>
4306
<a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="k">return</span> <span class="s2">&quot;ollama&quot;</span><span class="p">,</span> <span class="n">m</span><span class="o">.</span><span class="n">id</span>
4307
<a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
4308
<a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="k">pass</span>
4309
<a id="__codelineno-0-171" name="__codelineno-0-171"></a>
4310
<a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span>
4311
<a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="sa">f</span><span class="s2">&quot;No provider available for capability &#39;</span><span class="si">{</span><span class="n">capability</span><span class="si">}</span><span class="s2">&#39;. &quot;</span>
4312
<a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="s2">&quot;Set an API key for at least one provider, or start Ollama.&quot;</span>
4313
<a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="p">)</span>
4314
<a id="__codelineno-0-176" name="__codelineno-0-176"></a>
4315
<a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_track</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">provider</span><span class="p">:</span> <span class="n">BaseProvider</span><span class="p">,</span> <span class="n">prov_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">model</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
4316
<a id="__codelineno-0-178" name="__codelineno-0-178"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Record usage from the last API call on a provider.&quot;&quot;&quot;</span>
4317
<a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="n">last</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">provider</span><span class="p">,</span> <span class="s2">&quot;_last_usage&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
4318
<a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="k">if</span> <span class="n">last</span><span class="p">:</span>
4319
<a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="bp">self</span><span class="o">.</span><span class="n">usage</span><span class="o">.</span><span class="n">record</span><span class="p">(</span>
4320
<a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="n">provider</span><span class="o">=</span><span class="n">prov_name</span><span class="p">,</span>
4321
<a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">,</span>
4322
<a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="n">input_tokens</span><span class="o">=</span><span class="n">last</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;input_tokens&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
4323
<a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="n">output_tokens</span><span class="o">=</span><span class="n">last</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;output_tokens&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
4324
<a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="p">)</span>
4325
<a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="n">provider</span><span class="o">.</span><span class="n">_last_usage</span> <span class="o">=</span> <span class="kc">None</span>
4326
<a id="__codelineno-0-188" name="__codelineno-0-188"></a>
4327
<a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="c1"># --- Public API ---</span>
4328
<a id="__codelineno-0-190" name="__codelineno-0-190"></a>
4329
<a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="k">def</span><span class="w"> </span><span class="nf">chat</span><span class="p">(</span>
4330
<a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="bp">self</span><span class="p">,</span>
4331
<a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="n">messages</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">dict</span><span class="p">],</span>
4332
<a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
4333
<a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="n">temperature</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.7</span><span class="p">,</span>
4334
<a id="__codelineno-0-196" name="__codelineno-0-196"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
4335
<a id="__codelineno-0-197" name="__codelineno-0-197"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a chat completion to the best available provider.&quot;&quot;&quot;</span>
4336
<a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="n">prov_name</span><span class="p">,</span> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resolve_model</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">chat_model</span><span class="p">,</span> <span class="s2">&quot;chat&quot;</span><span class="p">,</span> <span class="n">_CHAT_PREFERENCES</span><span class="p">)</span>
4337
<a id="__codelineno-0-199" name="__codelineno-0-199"></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;Chat: using </span><span class="si">{</span><span class="n">prov_name</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">model</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4338
<a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="n">provider</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_provider</span><span class="p">(</span><span class="n">prov_name</span><span class="p">)</span>
4339
<a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="n">result</span> <span class="o">=</span> <span class="n">provider</span><span class="o">.</span><span class="n">chat</span><span class="p">(</span>
4340
<a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="n">messages</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="n">max_tokens</span><span class="p">,</span> <span class="n">temperature</span><span class="o">=</span><span class="n">temperature</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="n">model</span>
4341
<a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="p">)</span>
4342
<a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_track</span><span class="p">(</span><span class="n">provider</span><span class="p">,</span> <span class="n">prov_name</span><span class="p">,</span> <span class="n">model</span><span class="p">)</span>
4343
<a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="k">return</span> <span class="n">result</span>
4344
<a id="__codelineno-0-206" name="__codelineno-0-206"></a>
4345
<a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="k">def</span><span class="w"> </span><span class="nf">analyze_image</span><span class="p">(</span>
4346
<a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="bp">self</span><span class="p">,</span>
4347
<a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="n">image_bytes</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span>
4348
<a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="n">prompt</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
4349
<a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
4350
<a id="__codelineno-0-212" name="__codelineno-0-212"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
4351
<a id="__codelineno-0-213" name="__codelineno-0-213"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Analyze an image using the best available vision provider.&quot;&quot;&quot;</span>
4352
<a id="__codelineno-0-214" name="__codelineno-0-214"></a> <span class="n">prov_name</span><span class="p">,</span> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resolve_model</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vision_model</span><span class="p">,</span> <span class="s2">&quot;vision&quot;</span><span class="p">,</span> <span class="n">_VISION_PREFERENCES</span><span class="p">)</span>
4353
<a id="__codelineno-0-215" name="__codelineno-0-215"></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;Vision: using </span><span class="si">{</span><span class="n">prov_name</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">model</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4354
<a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">provider</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_provider</span><span class="p">(</span><span class="n">prov_name</span><span class="p">)</span>
4355
<a id="__codelineno-0-217" name="__codelineno-0-217"></a> <span class="n">result</span> <span class="o">=</span> <span class="n">provider</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">prompt</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="n">max_tokens</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">)</span>
4356
<a id="__codelineno-0-218" name="__codelineno-0-218"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_track</span><span class="p">(</span><span class="n">provider</span><span class="p">,</span> <span class="n">prov_name</span><span class="p">,</span> <span class="n">model</span><span class="p">)</span>
4357
<a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="k">return</span> <span class="n">result</span>
4358
<a id="__codelineno-0-220" name="__codelineno-0-220"></a>
4359
<a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="k">def</span><span class="w"> </span><span class="nf">transcribe_audio</span><span class="p">(</span>
4360
<a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="bp">self</span><span class="p">,</span>
4361
<a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="n">audio_path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Path</span><span class="p">,</span>
4362
<a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="n">language</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4363
<a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="n">speaker_hints</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4364
<a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
4365
<a id="__codelineno-0-227" name="__codelineno-0-227"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Transcribe audio using local Whisper if available, otherwise API.&quot;&quot;&quot;</span>
4366
<a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="c1"># Prefer local Whisper — no file size limits, no API costs</span>
4367
<a id="__codelineno-0-229" name="__codelineno-0-229"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;whisper-local&quot;</span><span class="p">):</span>
4368
<a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">try</span><span class="p">:</span>
4369
<a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.providers.whisper_local</span><span class="w"> </span><span class="kn">import</span> <span class="n">WhisperLocal</span>
4370
<a id="__codelineno-0-232" name="__codelineno-0-232"></a>
4371
<a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="k">if</span> <span class="n">WhisperLocal</span><span class="o">.</span><span class="n">is_available</span><span class="p">():</span>
4372
<a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="c1"># Parse model size from &quot;whisper-local:large&quot; or default to &quot;large&quot;</span>
4373
<a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="n">size</span> <span class="o">=</span> <span class="s2">&quot;large&quot;</span>
4374
<a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span> <span class="ow">and</span> <span class="s2">&quot;:&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span><span class="p">:</span>
4375
<a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="n">size</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;:&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
4376
<a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;_whisper_local&quot;</span><span class="p">):</span>
4377
<a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_whisper_local</span> <span class="o">=</span> <span class="n">WhisperLocal</span><span class="p">(</span><span class="n">model_size</span><span class="o">=</span><span class="n">size</span><span class="p">)</span>
4378
<a id="__codelineno-0-240" name="__codelineno-0-240"></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;Transcription: using local whisper-</span><span class="si">{</span><span class="n">size</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4379
<a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="c1"># Pass speaker names as initial prompt hint for Whisper</span>
4380
<a id="__codelineno-0-242" name="__codelineno-0-242"></a> <span class="n">whisper_kwargs</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;language&quot;</span><span class="p">:</span> <span class="n">language</span><span class="p">}</span>
4381
<a id="__codelineno-0-243" name="__codelineno-0-243"></a> <span class="k">if</span> <span class="n">speaker_hints</span><span class="p">:</span>
4382
<a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="n">whisper_kwargs</span><span class="p">[</span><span class="s2">&quot;initial_prompt&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
4383
<a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="s2">&quot;Speakers: &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="n">speaker_hints</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;.&quot;</span>
4384
<a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="p">)</span>
4385
<a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_whisper_local</span><span class="o">.</span><span class="n">transcribe</span><span class="p">(</span><span class="n">audio_path</span><span class="p">,</span> <span class="o">**</span><span class="n">whisper_kwargs</span><span class="p">)</span>
4386
<a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="n">duration</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;duration&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="mi">0</span>
4387
<a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="bp">self</span><span class="o">.</span><span class="n">usage</span><span class="o">.</span><span class="n">record</span><span class="p">(</span>
4388
<a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="n">provider</span><span class="o">=</span><span class="s2">&quot;local&quot;</span><span class="p">,</span>
4389
<a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="n">model</span><span class="o">=</span><span class="sa">f</span><span class="s2">&quot;whisper-</span><span class="si">{</span><span class="n">size</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">,</span>
4390
<a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="n">audio_minutes</span><span class="o">=</span><span class="n">duration</span> <span class="o">/</span> <span class="mi">60</span> <span class="k">if</span> <span class="n">duration</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span>
4391
<a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="p">)</span>
4392
<a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="k">return</span> <span class="n">result</span>
4393
<a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
4394
<a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="k">pass</span>
4395
<a id="__codelineno-0-257" name="__codelineno-0-257"></a>
4396
<a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="c1"># Fall back to API-based transcription</span>
4397
<a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="n">prov_name</span><span class="p">,</span> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resolve_model</span><span class="p">(</span>
4398
<a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span><span class="p">,</span> <span class="s2">&quot;audio&quot;</span><span class="p">,</span> <span class="n">_TRANSCRIPTION_PREFERENCES</span>
4399
<a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="p">)</span>
4400
<a id="__codelineno-0-262" name="__codelineno-0-262"></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;Transcription: using </span><span class="si">{</span><span class="n">prov_name</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">model</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4401
<a id="__codelineno-0-263" name="__codelineno-0-263"></a> <span class="n">provider</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_provider</span><span class="p">(</span><span class="n">prov_name</span><span class="p">)</span>
4402
<a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="c1"># Build transcription kwargs, passing speaker hints where supported</span>
4403
<a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="n">transcribe_kwargs</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;language&quot;</span><span class="p">:</span> <span class="n">language</span><span class="p">,</span> <span class="s2">&quot;model&quot;</span><span class="p">:</span> <span class="n">model</span><span class="p">}</span>
4404
<a id="__codelineno-0-266" name="__codelineno-0-266"></a> <span class="k">if</span> <span class="n">speaker_hints</span><span class="p">:</span>
4405
<a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="k">if</span> <span class="n">prov_name</span> <span class="o">==</span> <span class="s2">&quot;openai&quot;</span><span class="p">:</span>
4406
<a id="__codelineno-0-268" name="__codelineno-0-268"></a> <span class="c1"># OpenAI Whisper supports a &#39;prompt&#39; parameter for hints</span>
4407
<a id="__codelineno-0-269" name="__codelineno-0-269"></a> <span class="n">transcribe_kwargs</span><span class="p">[</span><span class="s2">&quot;prompt&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;Speakers: &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="n">speaker_hints</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;.&quot;</span>
4408
<a id="__codelineno-0-270" name="__codelineno-0-270"></a> <span class="k">else</span><span class="p">:</span>
4409
<a id="__codelineno-0-271" name="__codelineno-0-271"></a> <span class="n">transcribe_kwargs</span><span class="p">[</span><span class="s2">&quot;speaker_hints&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">speaker_hints</span>
4410
<a id="__codelineno-0-272" name="__codelineno-0-272"></a> <span class="n">result</span> <span class="o">=</span> <span class="n">provider</span><span class="o">.</span><span class="n">transcribe_audio</span><span class="p">(</span><span class="n">audio_path</span><span class="p">,</span> <span class="o">**</span><span class="n">transcribe_kwargs</span><span class="p">)</span>
4411
<a id="__codelineno-0-273" name="__codelineno-0-273"></a> <span class="n">duration</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;duration&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="mi">0</span>
4412
<a id="__codelineno-0-274" name="__codelineno-0-274"></a> <span class="bp">self</span><span class="o">.</span><span class="n">usage</span><span class="o">.</span><span class="n">record</span><span class="p">(</span>
4413
<a id="__codelineno-0-275" name="__codelineno-0-275"></a> <span class="n">provider</span><span class="o">=</span><span class="n">prov_name</span><span class="p">,</span>
4414
<a id="__codelineno-0-276" name="__codelineno-0-276"></a> <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">,</span>
4415
<a id="__codelineno-0-277" name="__codelineno-0-277"></a> <span class="n">audio_minutes</span><span class="o">=</span><span class="n">duration</span> <span class="o">/</span> <span class="mi">60</span> <span class="k">if</span> <span class="n">duration</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span>
4416
<a id="__codelineno-0-278" name="__codelineno-0-278"></a> <span class="p">)</span>
4417
<a id="__codelineno-0-279" name="__codelineno-0-279"></a> <span class="k">return</span> <span class="n">result</span>
4418
<a id="__codelineno-0-280" name="__codelineno-0-280"></a>
4419
<a id="__codelineno-0-281" name="__codelineno-0-281"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_models_used</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
4420
<a id="__codelineno-0-282" name="__codelineno-0-282"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return a dict mapping capability to &#39;provider/model&#39; for tracking.&quot;&quot;&quot;</span>
4421
<a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="n">result</span> <span class="o">=</span> <span class="p">{}</span>
4422
<a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="k">for</span> <span class="n">cap</span><span class="p">,</span> <span class="n">explicit</span><span class="p">,</span> <span class="n">prefs</span> <span class="ow">in</span> <span class="p">[</span>
4423
<a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="p">(</span><span class="s2">&quot;vision&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">vision_model</span><span class="p">,</span> <span class="n">_VISION_PREFERENCES</span><span class="p">),</span>
4424
<a id="__codelineno-0-286" name="__codelineno-0-286"></a> <span class="p">(</span><span class="s2">&quot;chat&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">chat_model</span><span class="p">,</span> <span class="n">_CHAT_PREFERENCES</span><span class="p">),</span>
4425
<a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="p">(</span><span class="s2">&quot;transcription&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span><span class="p">,</span> <span class="n">_TRANSCRIPTION_PREFERENCES</span><span class="p">),</span>
4426
<a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="p">]:</span>
4427
<a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="k">try</span><span class="p">:</span>
4428
<a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="n">prov</span><span class="p">,</span> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resolve_model</span><span class="p">(</span><span class="n">explicit</span><span class="p">,</span> <span class="n">cap</span><span class="p">,</span> <span class="n">prefs</span><span class="p">)</span>
4429
<a id="__codelineno-0-291" name="__codelineno-0-291"></a> <span class="n">result</span><span class="p">[</span><span class="n">cap</span><span class="p">]</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prov</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">model</span><span class="si">}</span><span class="s2">&quot;</span>
4430
<a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="k">except</span> <span class="ne">RuntimeError</span><span class="p">:</span>
4431
<a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="k">pass</span>
4432
<a id="__codelineno-0-294" name="__codelineno-0-294"></a> <span class="k">return</span> <span class="n">result</span>
4433
</code></pre></div></td></tr></table></div>
4434
</details>
4435
4436
4437
4438
<div class="doc doc-children">
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
<div class="doc doc-object doc-function">
4450
4451
4452
<h4 id="video_processor.providers.manager.ProviderManager.__init__" class="doc doc-heading">
4453
<code class="highlight language-python"><span class="fm">__init__</span><span class="p">(</span><span class="n">vision_model</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">chat_model</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">transcription_model</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">provider</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">auto</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></code>
4454
4455
<a href="#video_processor.providers.manager.ProviderManager.__init__" class="headerlink" title="Permanent link">&para;</a></h4>
4456
4457
4458
<div class="doc doc-contents ">
4459
4460
<p>Initialize the ProviderManager.</p>
4461
<h6 id="video_processor.providers.manager.ProviderManager.__init__--parameters">Parameters<a class="headerlink" href="#video_processor.providers.manager.ProviderManager.__init__--parameters" title="Permanent link">&para;</a></h6>
4462
<p>vision_model : override model for vision tasks (e.g. 'gpt-4o')
4463
chat_model : override model for chat/LLM tasks
4464
transcription_model : override model for transcription
4465
provider : force all tasks to a single provider ('openai', 'anthropic', 'gemini')
4466
auto : if True and no model specified, pick the best available</p>
4467
4468
4469
<details class="mkdocstrings-source">
4470
<summary>Source code in <code>video_processor/providers/manager.py</code></summary>
4471
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-60">60</a></span>
4472
<span class="normal"><a href="#__codelineno-0-61">61</a></span>
4473
<span class="normal"><a href="#__codelineno-0-62">62</a></span>
4474
<span class="normal"><a href="#__codelineno-0-63">63</a></span>
4475
<span class="normal"><a href="#__codelineno-0-64">64</a></span>
4476
<span class="normal"><a href="#__codelineno-0-65">65</a></span>
4477
<span class="normal"><a href="#__codelineno-0-66">66</a></span>
4478
<span class="normal"><a href="#__codelineno-0-67">67</a></span>
4479
<span class="normal"><a href="#__codelineno-0-68">68</a></span>
4480
<span class="normal"><a href="#__codelineno-0-69">69</a></span>
4481
<span class="normal"><a href="#__codelineno-0-70">70</a></span>
4482
<span class="normal"><a href="#__codelineno-0-71">71</a></span>
4483
<span class="normal"><a href="#__codelineno-0-72">72</a></span>
4484
<span class="normal"><a href="#__codelineno-0-73">73</a></span>
4485
<span class="normal"><a href="#__codelineno-0-74">74</a></span>
4486
<span class="normal"><a href="#__codelineno-0-75">75</a></span>
4487
<span class="normal"><a href="#__codelineno-0-76">76</a></span>
4488
<span class="normal"><a href="#__codelineno-0-77">77</a></span>
4489
<span class="normal"><a href="#__codelineno-0-78">78</a></span>
4490
<span class="normal"><a href="#__codelineno-0-79">79</a></span>
4491
<span class="normal"><a href="#__codelineno-0-80">80</a></span>
4492
<span class="normal"><a href="#__codelineno-0-81">81</a></span>
4493
<span class="normal"><a href="#__codelineno-0-82">82</a></span>
4494
<span class="normal"><a href="#__codelineno-0-83">83</a></span>
4495
<span class="normal"><a href="#__codelineno-0-84">84</a></span>
4496
<span class="normal"><a href="#__codelineno-0-85">85</a></span>
4497
<span class="normal"><a href="#__codelineno-0-86">86</a></span>
4498
<span class="normal"><a href="#__codelineno-0-87">87</a></span>
4499
<span class="normal"><a href="#__codelineno-0-88">88</a></span>
4500
<span class="normal"><a href="#__codelineno-0-89">89</a></span>
4501
<span class="normal"><a href="#__codelineno-0-90">90</a></span>
4502
<span class="normal"><a href="#__codelineno-0-91">91</a></span>
4503
<span class="normal"><a href="#__codelineno-0-92">92</a></span>
4504
<span class="normal"><a href="#__codelineno-0-93">93</a></span>
4505
<span class="normal"><a href="#__codelineno-0-94">94</a></span>
4506
<span class="normal"><a href="#__codelineno-0-95">95</a></span>
4507
<span class="normal"><a href="#__codelineno-0-96">96</a></span>
4508
<span class="normal"><a href="#__codelineno-0-97">97</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-60" name="__codelineno-0-60"></a><span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
4509
<a id="__codelineno-0-61" name="__codelineno-0-61"></a> <span class="bp">self</span><span class="p">,</span>
4510
<a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="n">vision_model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4511
<a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="n">chat_model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4512
<a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="n">transcription_model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4513
<a id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="n">provider</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4514
<a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="n">auto</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
4515
<a id="__codelineno-0-67" name="__codelineno-0-67"></a><span class="p">):</span>
4516
<a id="__codelineno-0-68" name="__codelineno-0-68"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4517
<a id="__codelineno-0-69" name="__codelineno-0-69"></a><span class="sd"> Initialize the ProviderManager.</span>
4518
<a id="__codelineno-0-70" name="__codelineno-0-70"></a>
4519
<a id="__codelineno-0-71" name="__codelineno-0-71"></a><span class="sd"> Parameters</span>
4520
<a id="__codelineno-0-72" name="__codelineno-0-72"></a><span class="sd"> ----------</span>
4521
<a id="__codelineno-0-73" name="__codelineno-0-73"></a><span class="sd"> vision_model : override model for vision tasks (e.g. &#39;gpt-4o&#39;)</span>
4522
<a id="__codelineno-0-74" name="__codelineno-0-74"></a><span class="sd"> chat_model : override model for chat/LLM tasks</span>
4523
<a id="__codelineno-0-75" name="__codelineno-0-75"></a><span class="sd"> transcription_model : override model for transcription</span>
4524
<a id="__codelineno-0-76" name="__codelineno-0-76"></a><span class="sd"> provider : force all tasks to a single provider (&#39;openai&#39;, &#39;anthropic&#39;, &#39;gemini&#39;)</span>
4525
<a id="__codelineno-0-77" name="__codelineno-0-77"></a><span class="sd"> auto : if True and no model specified, pick the best available</span>
4526
<a id="__codelineno-0-78" name="__codelineno-0-78"></a><span class="sd"> &quot;&quot;&quot;</span>
4527
<a id="__codelineno-0-79" name="__codelineno-0-79"></a> <span class="n">_ensure_providers_registered</span><span class="p">()</span>
4528
<a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="bp">self</span><span class="o">.</span><span class="n">auto</span> <span class="o">=</span> <span class="n">auto</span>
4529
<a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_providers</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">BaseProvider</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
4530
<a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_available_models</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="n">ModelInfo</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
4531
<a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="bp">self</span><span class="o">.</span><span class="n">usage</span> <span class="o">=</span> <span class="n">UsageTracker</span><span class="p">()</span>
4532
<a id="__codelineno-0-84" name="__codelineno-0-84"></a>
4533
<a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="c1"># If a single provider is forced, apply it</span>
4534
<a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="k">if</span> <span class="n">provider</span><span class="p">:</span>
4535
<a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="bp">self</span><span class="o">.</span><span class="n">vision_model</span> <span class="o">=</span> <span class="n">vision_model</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default_for_provider</span><span class="p">(</span><span class="n">provider</span><span class="p">,</span> <span class="s2">&quot;vision&quot;</span><span class="p">)</span>
4536
<a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="bp">self</span><span class="o">.</span><span class="n">chat_model</span> <span class="o">=</span> <span class="n">chat_model</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default_for_provider</span><span class="p">(</span><span class="n">provider</span><span class="p">,</span> <span class="s2">&quot;chat&quot;</span><span class="p">)</span>
4537
<a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span> <span class="o">=</span> <span class="n">transcription_model</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default_for_provider</span><span class="p">(</span>
4538
<a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="n">provider</span><span class="p">,</span> <span class="s2">&quot;audio&quot;</span>
4539
<a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="p">)</span>
4540
<a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="k">else</span><span class="p">:</span>
4541
<a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="bp">self</span><span class="o">.</span><span class="n">vision_model</span> <span class="o">=</span> <span class="n">vision_model</span>
4542
<a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="bp">self</span><span class="o">.</span><span class="n">chat_model</span> <span class="o">=</span> <span class="n">chat_model</span>
4543
<a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span> <span class="o">=</span> <span class="n">transcription_model</span>
4544
<a id="__codelineno-0-96" name="__codelineno-0-96"></a>
4545
<a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_forced_provider</span> <span class="o">=</span> <span class="n">provider</span>
4546
</code></pre></div></td></tr></table></div>
4547
</details>
4548
</div>
4549
4550
</div>
4551
4552
<div class="doc doc-object doc-function">
4553
4554
4555
<h4 id="video_processor.providers.manager.ProviderManager.analyze_image" class="doc doc-heading">
4556
<code class="highlight language-python"><span class="n">analyze_image</span><span class="p">(</span><span class="n">image_bytes</span><span class="p">,</span> <span class="n">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></code>
4557
4558
<a href="#video_processor.providers.manager.ProviderManager.analyze_image" class="headerlink" title="Permanent link">&para;</a></h4>
4559
4560
4561
<div class="doc doc-contents ">
4562
4563
<p>Analyze an image using the best available vision provider.</p>
4564
4565
4566
<details class="mkdocstrings-source">
4567
<summary>Source code in <code>video_processor/providers/manager.py</code></summary>
4568
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-207">207</a></span>
4569
<span class="normal"><a href="#__codelineno-0-208">208</a></span>
4570
<span class="normal"><a href="#__codelineno-0-209">209</a></span>
4571
<span class="normal"><a href="#__codelineno-0-210">210</a></span>
4572
<span class="normal"><a href="#__codelineno-0-211">211</a></span>
4573
<span class="normal"><a href="#__codelineno-0-212">212</a></span>
4574
<span class="normal"><a href="#__codelineno-0-213">213</a></span>
4575
<span class="normal"><a href="#__codelineno-0-214">214</a></span>
4576
<span class="normal"><a href="#__codelineno-0-215">215</a></span>
4577
<span class="normal"><a href="#__codelineno-0-216">216</a></span>
4578
<span class="normal"><a href="#__codelineno-0-217">217</a></span>
4579
<span class="normal"><a href="#__codelineno-0-218">218</a></span>
4580
<span class="normal"><a href="#__codelineno-0-219">219</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-207" name="__codelineno-0-207"></a><span class="k">def</span><span class="w"> </span><span class="nf">analyze_image</span><span class="p">(</span>
4581
<a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="bp">self</span><span class="p">,</span>
4582
<a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="n">image_bytes</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span>
4583
<a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="n">prompt</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
4584
<a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
4585
<a id="__codelineno-0-212" name="__codelineno-0-212"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
4586
<a id="__codelineno-0-213" name="__codelineno-0-213"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Analyze an image using the best available vision provider.&quot;&quot;&quot;</span>
4587
<a id="__codelineno-0-214" name="__codelineno-0-214"></a> <span class="n">prov_name</span><span class="p">,</span> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resolve_model</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vision_model</span><span class="p">,</span> <span class="s2">&quot;vision&quot;</span><span class="p">,</span> <span class="n">_VISION_PREFERENCES</span><span class="p">)</span>
4588
<a id="__codelineno-0-215" name="__codelineno-0-215"></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;Vision: using </span><span class="si">{</span><span class="n">prov_name</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">model</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4589
<a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">provider</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_provider</span><span class="p">(</span><span class="n">prov_name</span><span class="p">)</span>
4590
<a id="__codelineno-0-217" name="__codelineno-0-217"></a> <span class="n">result</span> <span class="o">=</span> <span class="n">provider</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">prompt</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="n">max_tokens</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">)</span>
4591
<a id="__codelineno-0-218" name="__codelineno-0-218"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_track</span><span class="p">(</span><span class="n">provider</span><span class="p">,</span> <span class="n">prov_name</span><span class="p">,</span> <span class="n">model</span><span class="p">)</span>
4592
<a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="k">return</span> <span class="n">result</span>
4593
</code></pre></div></td></tr></table></div>
4594
</details>
4595
</div>
4596
4597
</div>
4598
4599
<div class="doc doc-object doc-function">
4600
4601
4602
<h4 id="video_processor.providers.manager.ProviderManager.chat" class="doc doc-heading">
4603
<code class="highlight language-python"><span class="n">chat</span><span class="p">(</span><span class="n">messages</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">4096</span><span class="p">,</span> <span class="n">temperature</span><span class="o">=</span><span class="mf">0.7</span><span class="p">)</span></code>
4604
4605
<a href="#video_processor.providers.manager.ProviderManager.chat" class="headerlink" title="Permanent link">&para;</a></h4>
4606
4607
4608
<div class="doc doc-contents ">
4609
4610
<p>Send a chat completion to the best available provider.</p>
4611
4612
4613
<details class="mkdocstrings-source">
4614
<summary>Source code in <code>video_processor/providers/manager.py</code></summary>
4615
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-191">191</a></span>
4616
<span class="normal"><a href="#__codelineno-0-192">192</a></span>
4617
<span class="normal"><a href="#__codelineno-0-193">193</a></span>
4618
<span class="normal"><a href="#__codelineno-0-194">194</a></span>
4619
<span class="normal"><a href="#__codelineno-0-195">195</a></span>
4620
<span class="normal"><a href="#__codelineno-0-196">196</a></span>
4621
<span class="normal"><a href="#__codelineno-0-197">197</a></span>
4622
<span class="normal"><a href="#__codelineno-0-198">198</a></span>
4623
<span class="normal"><a href="#__codelineno-0-199">199</a></span>
4624
<span class="normal"><a href="#__codelineno-0-200">200</a></span>
4625
<span class="normal"><a href="#__codelineno-0-201">201</a></span>
4626
<span class="normal"><a href="#__codelineno-0-202">202</a></span>
4627
<span class="normal"><a href="#__codelineno-0-203">203</a></span>
4628
<span class="normal"><a href="#__codelineno-0-204">204</a></span>
4629
<span class="normal"><a href="#__codelineno-0-205">205</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-191" name="__codelineno-0-191"></a><span class="k">def</span><span class="w"> </span><span class="nf">chat</span><span class="p">(</span>
4630
<a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="bp">self</span><span class="p">,</span>
4631
<a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="n">messages</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">dict</span><span class="p">],</span>
4632
<a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
4633
<a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="n">temperature</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.7</span><span class="p">,</span>
4634
<a id="__codelineno-0-196" name="__codelineno-0-196"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
4635
<a id="__codelineno-0-197" name="__codelineno-0-197"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a chat completion to the best available provider.&quot;&quot;&quot;</span>
4636
<a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="n">prov_name</span><span class="p">,</span> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resolve_model</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">chat_model</span><span class="p">,</span> <span class="s2">&quot;chat&quot;</span><span class="p">,</span> <span class="n">_CHAT_PREFERENCES</span><span class="p">)</span>
4637
<a id="__codelineno-0-199" name="__codelineno-0-199"></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;Chat: using </span><span class="si">{</span><span class="n">prov_name</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">model</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4638
<a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="n">provider</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_provider</span><span class="p">(</span><span class="n">prov_name</span><span class="p">)</span>
4639
<a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="n">result</span> <span class="o">=</span> <span class="n">provider</span><span class="o">.</span><span class="n">chat</span><span class="p">(</span>
4640
<a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="n">messages</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="n">max_tokens</span><span class="p">,</span> <span class="n">temperature</span><span class="o">=</span><span class="n">temperature</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="n">model</span>
4641
<a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="p">)</span>
4642
<a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_track</span><span class="p">(</span><span class="n">provider</span><span class="p">,</span> <span class="n">prov_name</span><span class="p">,</span> <span class="n">model</span><span class="p">)</span>
4643
<a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="k">return</span> <span class="n">result</span>
4644
</code></pre></div></td></tr></table></div>
4645
</details>
4646
</div>
4647
4648
</div>
4649
4650
<div class="doc doc-object doc-function">
4651
4652
4653
<h4 id="video_processor.providers.manager.ProviderManager.get_models_used" class="doc doc-heading">
4654
<code class="highlight language-python"><span class="n">get_models_used</span><span class="p">()</span></code>
4655
4656
<a href="#video_processor.providers.manager.ProviderManager.get_models_used" class="headerlink" title="Permanent link">&para;</a></h4>
4657
4658
4659
<div class="doc doc-contents ">
4660
4661
<p>Return a dict mapping capability to 'provider/model' for tracking.</p>
4662
4663
4664
<details class="mkdocstrings-source">
4665
<summary>Source code in <code>video_processor/providers/manager.py</code></summary>
4666
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-281">281</a></span>
4667
<span class="normal"><a href="#__codelineno-0-282">282</a></span>
4668
<span class="normal"><a href="#__codelineno-0-283">283</a></span>
4669
<span class="normal"><a href="#__codelineno-0-284">284</a></span>
4670
<span class="normal"><a href="#__codelineno-0-285">285</a></span>
4671
<span class="normal"><a href="#__codelineno-0-286">286</a></span>
4672
<span class="normal"><a href="#__codelineno-0-287">287</a></span>
4673
<span class="normal"><a href="#__codelineno-0-288">288</a></span>
4674
<span class="normal"><a href="#__codelineno-0-289">289</a></span>
4675
<span class="normal"><a href="#__codelineno-0-290">290</a></span>
4676
<span class="normal"><a href="#__codelineno-0-291">291</a></span>
4677
<span class="normal"><a href="#__codelineno-0-292">292</a></span>
4678
<span class="normal"><a href="#__codelineno-0-293">293</a></span>
4679
<span class="normal"><a href="#__codelineno-0-294">294</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-281" name="__codelineno-0-281"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_models_used</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
4680
<a id="__codelineno-0-282" name="__codelineno-0-282"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Return a dict mapping capability to &#39;provider/model&#39; for tracking.&quot;&quot;&quot;</span>
4681
<a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="n">result</span> <span class="o">=</span> <span class="p">{}</span>
4682
<a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="k">for</span> <span class="n">cap</span><span class="p">,</span> <span class="n">explicit</span><span class="p">,</span> <span class="n">prefs</span> <span class="ow">in</span> <span class="p">[</span>
4683
<a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="p">(</span><span class="s2">&quot;vision&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">vision_model</span><span class="p">,</span> <span class="n">_VISION_PREFERENCES</span><span class="p">),</span>
4684
<a id="__codelineno-0-286" name="__codelineno-0-286"></a> <span class="p">(</span><span class="s2">&quot;chat&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">chat_model</span><span class="p">,</span> <span class="n">_CHAT_PREFERENCES</span><span class="p">),</span>
4685
<a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="p">(</span><span class="s2">&quot;transcription&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span><span class="p">,</span> <span class="n">_TRANSCRIPTION_PREFERENCES</span><span class="p">),</span>
4686
<a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="p">]:</span>
4687
<a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="k">try</span><span class="p">:</span>
4688
<a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="n">prov</span><span class="p">,</span> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resolve_model</span><span class="p">(</span><span class="n">explicit</span><span class="p">,</span> <span class="n">cap</span><span class="p">,</span> <span class="n">prefs</span><span class="p">)</span>
4689
<a id="__codelineno-0-291" name="__codelineno-0-291"></a> <span class="n">result</span><span class="p">[</span><span class="n">cap</span><span class="p">]</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prov</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">model</span><span class="si">}</span><span class="s2">&quot;</span>
4690
<a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="k">except</span> <span class="ne">RuntimeError</span><span class="p">:</span>
4691
<a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="k">pass</span>
4692
<a id="__codelineno-0-294" name="__codelineno-0-294"></a> <span class="k">return</span> <span class="n">result</span>
4693
</code></pre></div></td></tr></table></div>
4694
</details>
4695
</div>
4696
4697
</div>
4698
4699
<div class="doc doc-object doc-function">
4700
4701
4702
<h4 id="video_processor.providers.manager.ProviderManager.transcribe_audio" class="doc doc-heading">
4703
<code class="highlight language-python"><span class="n">transcribe_audio</span><span class="p">(</span><span class="n">audio_path</span><span class="p">,</span> <span class="n">language</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">speaker_hints</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code>
4704
4705
<a href="#video_processor.providers.manager.ProviderManager.transcribe_audio" class="headerlink" title="Permanent link">&para;</a></h4>
4706
4707
4708
<div class="doc doc-contents ">
4709
4710
<p>Transcribe audio using local Whisper if available, otherwise API.</p>
4711
4712
4713
<details class="mkdocstrings-source">
4714
<summary>Source code in <code>video_processor/providers/manager.py</code></summary>
4715
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-221">221</a></span>
4716
<span class="normal"><a href="#__codelineno-0-222">222</a></span>
4717
<span class="normal"><a href="#__codelineno-0-223">223</a></span>
4718
<span class="normal"><a href="#__codelineno-0-224">224</a></span>
4719
<span class="normal"><a href="#__codelineno-0-225">225</a></span>
4720
<span class="normal"><a href="#__codelineno-0-226">226</a></span>
4721
<span class="normal"><a href="#__codelineno-0-227">227</a></span>
4722
<span class="normal"><a href="#__codelineno-0-228">228</a></span>
4723
<span class="normal"><a href="#__codelineno-0-229">229</a></span>
4724
<span class="normal"><a href="#__codelineno-0-230">230</a></span>
4725
<span class="normal"><a href="#__codelineno-0-231">231</a></span>
4726
<span class="normal"><a href="#__codelineno-0-232">232</a></span>
4727
<span class="normal"><a href="#__codelineno-0-233">233</a></span>
4728
<span class="normal"><a href="#__codelineno-0-234">234</a></span>
4729
<span class="normal"><a href="#__codelineno-0-235">235</a></span>
4730
<span class="normal"><a href="#__codelineno-0-236">236</a></span>
4731
<span class="normal"><a href="#__codelineno-0-237">237</a></span>
4732
<span class="normal"><a href="#__codelineno-0-238">238</a></span>
4733
<span class="normal"><a href="#__codelineno-0-239">239</a></span>
4734
<span class="normal"><a href="#__codelineno-0-240">240</a></span>
4735
<span class="normal"><a href="#__codelineno-0-241">241</a></span>
4736
<span class="normal"><a href="#__codelineno-0-242">242</a></span>
4737
<span class="normal"><a href="#__codelineno-0-243">243</a></span>
4738
<span class="normal"><a href="#__codelineno-0-244">244</a></span>
4739
<span class="normal"><a href="#__codelineno-0-245">245</a></span>
4740
<span class="normal"><a href="#__codelineno-0-246">246</a></span>
4741
<span class="normal"><a href="#__codelineno-0-247">247</a></span>
4742
<span class="normal"><a href="#__codelineno-0-248">248</a></span>
4743
<span class="normal"><a href="#__codelineno-0-249">249</a></span>
4744
<span class="normal"><a href="#__codelineno-0-250">250</a></span>
4745
<span class="normal"><a href="#__codelineno-0-251">251</a></span>
4746
<span class="normal"><a href="#__codelineno-0-252">252</a></span>
4747
<span class="normal"><a href="#__codelineno-0-253">253</a></span>
4748
<span class="normal"><a href="#__codelineno-0-254">254</a></span>
4749
<span class="normal"><a href="#__codelineno-0-255">255</a></span>
4750
<span class="normal"><a href="#__codelineno-0-256">256</a></span>
4751
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
4752
<span class="normal"><a href="#__codelineno-0-258">258</a></span>
4753
<span class="normal"><a href="#__codelineno-0-259">259</a></span>
4754
<span class="normal"><a href="#__codelineno-0-260">260</a></span>
4755
<span class="normal"><a href="#__codelineno-0-261">261</a></span>
4756
<span class="normal"><a href="#__codelineno-0-262">262</a></span>
4757
<span class="normal"><a href="#__codelineno-0-263">263</a></span>
4758
<span class="normal"><a href="#__codelineno-0-264">264</a></span>
4759
<span class="normal"><a href="#__codelineno-0-265">265</a></span>
4760
<span class="normal"><a href="#__codelineno-0-266">266</a></span>
4761
<span class="normal"><a href="#__codelineno-0-267">267</a></span>
4762
<span class="normal"><a href="#__codelineno-0-268">268</a></span>
4763
<span class="normal"><a href="#__codelineno-0-269">269</a></span>
4764
<span class="normal"><a href="#__codelineno-0-270">270</a></span>
4765
<span class="normal"><a href="#__codelineno-0-271">271</a></span>
4766
<span class="normal"><a href="#__codelineno-0-272">272</a></span>
4767
<span class="normal"><a href="#__codelineno-0-273">273</a></span>
4768
<span class="normal"><a href="#__codelineno-0-274">274</a></span>
4769
<span class="normal"><a href="#__codelineno-0-275">275</a></span>
4770
<span class="normal"><a href="#__codelineno-0-276">276</a></span>
4771
<span class="normal"><a href="#__codelineno-0-277">277</a></span>
4772
<span class="normal"><a href="#__codelineno-0-278">278</a></span>
4773
<span class="normal"><a href="#__codelineno-0-279">279</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-221" name="__codelineno-0-221"></a><span class="k">def</span><span class="w"> </span><span class="nf">transcribe_audio</span><span class="p">(</span>
4774
<a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="bp">self</span><span class="p">,</span>
4775
<a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="n">audio_path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Path</span><span class="p">,</span>
4776
<a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="n">language</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4777
<a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="n">speaker_hints</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4778
<a id="__codelineno-0-226" name="__codelineno-0-226"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
4779
<a id="__codelineno-0-227" name="__codelineno-0-227"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Transcribe audio using local Whisper if available, otherwise API.&quot;&quot;&quot;</span>
4780
<a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="c1"># Prefer local Whisper — no file size limits, no API costs</span>
4781
<a id="__codelineno-0-229" name="__codelineno-0-229"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;whisper-local&quot;</span><span class="p">):</span>
4782
<a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">try</span><span class="p">:</span>
4783
<a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.providers.whisper_local</span><span class="w"> </span><span class="kn">import</span> <span class="n">WhisperLocal</span>
4784
<a id="__codelineno-0-232" name="__codelineno-0-232"></a>
4785
<a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="k">if</span> <span class="n">WhisperLocal</span><span class="o">.</span><span class="n">is_available</span><span class="p">():</span>
4786
<a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="c1"># Parse model size from &quot;whisper-local:large&quot; or default to &quot;large&quot;</span>
4787
<a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="n">size</span> <span class="o">=</span> <span class="s2">&quot;large&quot;</span>
4788
<a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span> <span class="ow">and</span> <span class="s2">&quot;:&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span><span class="p">:</span>
4789
<a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="n">size</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;:&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
4790
<a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;_whisper_local&quot;</span><span class="p">):</span>
4791
<a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_whisper_local</span> <span class="o">=</span> <span class="n">WhisperLocal</span><span class="p">(</span><span class="n">model_size</span><span class="o">=</span><span class="n">size</span><span class="p">)</span>
4792
<a id="__codelineno-0-240" name="__codelineno-0-240"></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;Transcription: using local whisper-</span><span class="si">{</span><span class="n">size</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4793
<a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="c1"># Pass speaker names as initial prompt hint for Whisper</span>
4794
<a id="__codelineno-0-242" name="__codelineno-0-242"></a> <span class="n">whisper_kwargs</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;language&quot;</span><span class="p">:</span> <span class="n">language</span><span class="p">}</span>
4795
<a id="__codelineno-0-243" name="__codelineno-0-243"></a> <span class="k">if</span> <span class="n">speaker_hints</span><span class="p">:</span>
4796
<a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="n">whisper_kwargs</span><span class="p">[</span><span class="s2">&quot;initial_prompt&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
4797
<a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="s2">&quot;Speakers: &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="n">speaker_hints</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;.&quot;</span>
4798
<a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="p">)</span>
4799
<a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_whisper_local</span><span class="o">.</span><span class="n">transcribe</span><span class="p">(</span><span class="n">audio_path</span><span class="p">,</span> <span class="o">**</span><span class="n">whisper_kwargs</span><span class="p">)</span>
4800
<a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="n">duration</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;duration&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="mi">0</span>
4801
<a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="bp">self</span><span class="o">.</span><span class="n">usage</span><span class="o">.</span><span class="n">record</span><span class="p">(</span>
4802
<a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="n">provider</span><span class="o">=</span><span class="s2">&quot;local&quot;</span><span class="p">,</span>
4803
<a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="n">model</span><span class="o">=</span><span class="sa">f</span><span class="s2">&quot;whisper-</span><span class="si">{</span><span class="n">size</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">,</span>
4804
<a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="n">audio_minutes</span><span class="o">=</span><span class="n">duration</span> <span class="o">/</span> <span class="mi">60</span> <span class="k">if</span> <span class="n">duration</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span>
4805
<a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="p">)</span>
4806
<a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="k">return</span> <span class="n">result</span>
4807
<a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
4808
<a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="k">pass</span>
4809
<a id="__codelineno-0-257" name="__codelineno-0-257"></a>
4810
<a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="c1"># Fall back to API-based transcription</span>
4811
<a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="n">prov_name</span><span class="p">,</span> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resolve_model</span><span class="p">(</span>
4812
<a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="bp">self</span><span class="o">.</span><span class="n">transcription_model</span><span class="p">,</span> <span class="s2">&quot;audio&quot;</span><span class="p">,</span> <span class="n">_TRANSCRIPTION_PREFERENCES</span>
4813
<a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="p">)</span>
4814
<a id="__codelineno-0-262" name="__codelineno-0-262"></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;Transcription: using </span><span class="si">{</span><span class="n">prov_name</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">model</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4815
<a id="__codelineno-0-263" name="__codelineno-0-263"></a> <span class="n">provider</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_provider</span><span class="p">(</span><span class="n">prov_name</span><span class="p">)</span>
4816
<a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="c1"># Build transcription kwargs, passing speaker hints where supported</span>
4817
<a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="n">transcribe_kwargs</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;language&quot;</span><span class="p">:</span> <span class="n">language</span><span class="p">,</span> <span class="s2">&quot;model&quot;</span><span class="p">:</span> <span class="n">model</span><span class="p">}</span>
4818
<a id="__codelineno-0-266" name="__codelineno-0-266"></a> <span class="k">if</span> <span class="n">speaker_hints</span><span class="p">:</span>
4819
<a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="k">if</span> <span class="n">prov_name</span> <span class="o">==</span> <span class="s2">&quot;openai&quot;</span><span class="p">:</span>
4820
<a id="__codelineno-0-268" name="__codelineno-0-268"></a> <span class="c1"># OpenAI Whisper supports a &#39;prompt&#39; parameter for hints</span>
4821
<a id="__codelineno-0-269" name="__codelineno-0-269"></a> <span class="n">transcribe_kwargs</span><span class="p">[</span><span class="s2">&quot;prompt&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;Speakers: &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="n">speaker_hints</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;.&quot;</span>
4822
<a id="__codelineno-0-270" name="__codelineno-0-270"></a> <span class="k">else</span><span class="p">:</span>
4823
<a id="__codelineno-0-271" name="__codelineno-0-271"></a> <span class="n">transcribe_kwargs</span><span class="p">[</span><span class="s2">&quot;speaker_hints&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">speaker_hints</span>
4824
<a id="__codelineno-0-272" name="__codelineno-0-272"></a> <span class="n">result</span> <span class="o">=</span> <span class="n">provider</span><span class="o">.</span><span class="n">transcribe_audio</span><span class="p">(</span><span class="n">audio_path</span><span class="p">,</span> <span class="o">**</span><span class="n">transcribe_kwargs</span><span class="p">)</span>
4825
<a id="__codelineno-0-273" name="__codelineno-0-273"></a> <span class="n">duration</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;duration&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="mi">0</span>
4826
<a id="__codelineno-0-274" name="__codelineno-0-274"></a> <span class="bp">self</span><span class="o">.</span><span class="n">usage</span><span class="o">.</span><span class="n">record</span><span class="p">(</span>
4827
<a id="__codelineno-0-275" name="__codelineno-0-275"></a> <span class="n">provider</span><span class="o">=</span><span class="n">prov_name</span><span class="p">,</span>
4828
<a id="__codelineno-0-276" name="__codelineno-0-276"></a> <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">,</span>
4829
<a id="__codelineno-0-277" name="__codelineno-0-277"></a> <span class="n">audio_minutes</span><span class="o">=</span><span class="n">duration</span> <span class="o">/</span> <span class="mi">60</span> <span class="k">if</span> <span class="n">duration</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span>
4830
<a id="__codelineno-0-278" name="__codelineno-0-278"></a> <span class="p">)</span>
4831
<a id="__codelineno-0-279" name="__codelineno-0-279"></a> <span class="k">return</span> <span class="n">result</span>
4832
</code></pre></div></td></tr></table></div>
4833
</details>
4834
</div>
4835
4836
</div>
4837
4838
4839
4840
</div>
4841
4842
</div>
4843
4844
</div>
4845
4846
4847
4848
4849
</div>
4850
4851
</div>
4852
4853
</div>
4854
4855
<div class="doc doc-object doc-module">
4856
4857
4858
4859
<h2 id="video_processor.providers.discovery" class="doc doc-heading">
4860
<code>video_processor.providers.discovery</code>
4861
4862
4863
<a href="#video_processor.providers.discovery" class="headerlink" title="Permanent link">&para;</a></h2>
4864
4865
<div class="doc doc-contents first">
4866
4867
<p>Auto-discover available models across providers.</p>
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
<div class="doc doc-children">
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
<div class="doc doc-object doc-function">
4890
4891
4892
<h3 id="video_processor.providers.discovery.clear_discovery_cache" class="doc doc-heading">
4893
<code class="highlight language-python"><span class="n">clear_discovery_cache</span><span class="p">()</span></code>
4894
4895
<a href="#video_processor.providers.discovery.clear_discovery_cache" class="headerlink" title="Permanent link">&para;</a></h3>
4896
4897
4898
<div class="doc doc-contents ">
4899
4900
<p>Clear the cached model list.</p>
4901
4902
4903
<details class="mkdocstrings-source">
4904
<summary>Source code in <code>video_processor/providers/discovery.py</code></summary>
4905
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-102">102</a></span>
4906
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
4907
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
4908
<span class="normal"><a href="#__codelineno-0-105">105</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-102" name="__codelineno-0-102"></a><span class="k">def</span><span class="w"> </span><span class="nf">clear_discovery_cache</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
4909
<a id="__codelineno-0-103" name="__codelineno-0-103"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Clear the cached model list.&quot;&quot;&quot;</span>
4910
<a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="k">global</span> <span class="n">_cached_models</span>
4911
<a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="n">_cached_models</span> <span class="o">=</span> <span class="kc">None</span>
4912
</code></pre></div></td></tr></table></div>
4913
</details>
4914
</div>
4915
4916
</div>
4917
4918
<div class="doc doc-object doc-function">
4919
4920
4921
<h3 id="video_processor.providers.discovery.discover_available_models" class="doc doc-heading">
4922
<code class="highlight language-python"><span class="n">discover_available_models</span><span class="p">(</span><span class="n">api_keys</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">force_refresh</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span></code>
4923
4924
<a href="#video_processor.providers.discovery.discover_available_models" class="headerlink" title="Permanent link">&para;</a></h3>
4925
4926
4927
<div class="doc doc-contents ">
4928
4929
<p>Discover available models from all configured providers.</p>
4930
<p>For each provider with a valid API key, calls list_models() and returns
4931
a unified list. Results are cached for the session.</p>
4932
4933
4934
<details class="mkdocstrings-source">
4935
<summary>Source code in <code>video_processor/providers/discovery.py</code></summary>
4936
<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>
4937
<span class="normal"><a href="#__codelineno-0-28">28</a></span>
4938
<span class="normal"><a href="#__codelineno-0-29">29</a></span>
4939
<span class="normal"><a href="#__codelineno-0-30">30</a></span>
4940
<span class="normal"><a href="#__codelineno-0-31">31</a></span>
4941
<span class="normal"><a href="#__codelineno-0-32">32</a></span>
4942
<span class="normal"><a href="#__codelineno-0-33">33</a></span>
4943
<span class="normal"><a href="#__codelineno-0-34">34</a></span>
4944
<span class="normal"><a href="#__codelineno-0-35">35</a></span>
4945
<span class="normal"><a href="#__codelineno-0-36">36</a></span>
4946
<span class="normal"><a href="#__codelineno-0-37">37</a></span>
4947
<span class="normal"><a href="#__codelineno-0-38">38</a></span>
4948
<span class="normal"><a href="#__codelineno-0-39">39</a></span>
4949
<span class="normal"><a href="#__codelineno-0-40">40</a></span>
4950
<span class="normal"><a href="#__codelineno-0-41">41</a></span>
4951
<span class="normal"><a href="#__codelineno-0-42">42</a></span>
4952
<span class="normal"><a href="#__codelineno-0-43">43</a></span>
4953
<span class="normal"><a href="#__codelineno-0-44">44</a></span>
4954
<span class="normal"><a href="#__codelineno-0-45">45</a></span>
4955
<span class="normal"><a href="#__codelineno-0-46">46</a></span>
4956
<span class="normal"><a href="#__codelineno-0-47">47</a></span>
4957
<span class="normal"><a href="#__codelineno-0-48">48</a></span>
4958
<span class="normal"><a href="#__codelineno-0-49">49</a></span>
4959
<span class="normal"><a href="#__codelineno-0-50">50</a></span>
4960
<span class="normal"><a href="#__codelineno-0-51">51</a></span>
4961
<span class="normal"><a href="#__codelineno-0-52">52</a></span>
4962
<span class="normal"><a href="#__codelineno-0-53">53</a></span>
4963
<span class="normal"><a href="#__codelineno-0-54">54</a></span>
4964
<span class="normal"><a href="#__codelineno-0-55">55</a></span>
4965
<span class="normal"><a href="#__codelineno-0-56">56</a></span>
4966
<span class="normal"><a href="#__codelineno-0-57">57</a></span>
4967
<span class="normal"><a href="#__codelineno-0-58">58</a></span>
4968
<span class="normal"><a href="#__codelineno-0-59">59</a></span>
4969
<span class="normal"><a href="#__codelineno-0-60">60</a></span>
4970
<span class="normal"><a href="#__codelineno-0-61">61</a></span>
4971
<span class="normal"><a href="#__codelineno-0-62">62</a></span>
4972
<span class="normal"><a href="#__codelineno-0-63">63</a></span>
4973
<span class="normal"><a href="#__codelineno-0-64">64</a></span>
4974
<span class="normal"><a href="#__codelineno-0-65">65</a></span>
4975
<span class="normal"><a href="#__codelineno-0-66">66</a></span>
4976
<span class="normal"><a href="#__codelineno-0-67">67</a></span>
4977
<span class="normal"><a href="#__codelineno-0-68">68</a></span>
4978
<span class="normal"><a href="#__codelineno-0-69">69</a></span>
4979
<span class="normal"><a href="#__codelineno-0-70">70</a></span>
4980
<span class="normal"><a href="#__codelineno-0-71">71</a></span>
4981
<span class="normal"><a href="#__codelineno-0-72">72</a></span>
4982
<span class="normal"><a href="#__codelineno-0-73">73</a></span>
4983
<span class="normal"><a href="#__codelineno-0-74">74</a></span>
4984
<span class="normal"><a href="#__codelineno-0-75">75</a></span>
4985
<span class="normal"><a href="#__codelineno-0-76">76</a></span>
4986
<span class="normal"><a href="#__codelineno-0-77">77</a></span>
4987
<span class="normal"><a href="#__codelineno-0-78">78</a></span>
4988
<span class="normal"><a href="#__codelineno-0-79">79</a></span>
4989
<span class="normal"><a href="#__codelineno-0-80">80</a></span>
4990
<span class="normal"><a href="#__codelineno-0-81">81</a></span>
4991
<span class="normal"><a href="#__codelineno-0-82">82</a></span>
4992
<span class="normal"><a href="#__codelineno-0-83">83</a></span>
4993
<span class="normal"><a href="#__codelineno-0-84">84</a></span>
4994
<span class="normal"><a href="#__codelineno-0-85">85</a></span>
4995
<span class="normal"><a href="#__codelineno-0-86">86</a></span>
4996
<span class="normal"><a href="#__codelineno-0-87">87</a></span>
4997
<span class="normal"><a href="#__codelineno-0-88">88</a></span>
4998
<span class="normal"><a href="#__codelineno-0-89">89</a></span>
4999
<span class="normal"><a href="#__codelineno-0-90">90</a></span>
5000
<span class="normal"><a href="#__codelineno-0-91">91</a></span>
5001
<span class="normal"><a href="#__codelineno-0-92">92</a></span>
5002
<span class="normal"><a href="#__codelineno-0-93">93</a></span>
5003
<span class="normal"><a href="#__codelineno-0-94">94</a></span>
5004
<span class="normal"><a href="#__codelineno-0-95">95</a></span>
5005
<span class="normal"><a href="#__codelineno-0-96">96</a></span>
5006
<span class="normal"><a href="#__codelineno-0-97">97</a></span>
5007
<span class="normal"><a href="#__codelineno-0-98">98</a></span>
5008
<span class="normal"><a href="#__codelineno-0-99">99</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">def</span><span class="w"> </span><span class="nf">discover_available_models</span><span class="p">(</span>
5009
<a id="__codelineno-0-28" name="__codelineno-0-28"></a> <span class="n">api_keys</span><span class="p">:</span> <span class="n">Optional</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="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5010
<a id="__codelineno-0-29" name="__codelineno-0-29"></a> <span class="n">force_refresh</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
5011
<a id="__codelineno-0-30" name="__codelineno-0-30"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ModelInfo</span><span class="p">]:</span>
5012
<a id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
5013
<a id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="sd"> Discover available models from all configured providers.</span>
5014
<a id="__codelineno-0-33" name="__codelineno-0-33"></a>
5015
<a id="__codelineno-0-34" name="__codelineno-0-34"></a><span class="sd"> For each provider with a valid API key, calls list_models() and returns</span>
5016
<a id="__codelineno-0-35" name="__codelineno-0-35"></a><span class="sd"> a unified list. Results are cached for the session.</span>
5017
<a id="__codelineno-0-36" name="__codelineno-0-36"></a><span class="sd"> &quot;&quot;&quot;</span>
5018
<a id="__codelineno-0-37" name="__codelineno-0-37"></a> <span class="k">global</span> <span class="n">_cached_models</span>
5019
<a id="__codelineno-0-38" name="__codelineno-0-38"></a> <span class="k">if</span> <span class="n">_cached_models</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">force_refresh</span><span class="p">:</span>
5020
<a id="__codelineno-0-39" name="__codelineno-0-39"></a> <span class="k">return</span> <span class="n">_cached_models</span>
5021
<a id="__codelineno-0-40" name="__codelineno-0-40"></a>
5022
<a id="__codelineno-0-41" name="__codelineno-0-41"></a> <span class="n">_ensure_providers_registered</span><span class="p">()</span>
5023
<a id="__codelineno-0-42" name="__codelineno-0-42"></a>
5024
<a id="__codelineno-0-43" name="__codelineno-0-43"></a> <span class="n">keys</span> <span class="o">=</span> <span class="n">api_keys</span> <span class="ow">or</span> <span class="p">{</span>
5025
<a id="__codelineno-0-44" name="__codelineno-0-44"></a> <span class="s2">&quot;openai&quot;</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&quot;OPENAI_API_KEY&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">),</span>
5026
<a id="__codelineno-0-45" name="__codelineno-0-45"></a> <span class="s2">&quot;anthropic&quot;</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&quot;ANTHROPIC_API_KEY&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">),</span>
5027
<a id="__codelineno-0-46" name="__codelineno-0-46"></a> <span class="s2">&quot;gemini&quot;</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&quot;GEMINI_API_KEY&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">),</span>
5028
<a id="__codelineno-0-47" name="__codelineno-0-47"></a> <span class="p">}</span>
5029
<a id="__codelineno-0-48" name="__codelineno-0-48"></a>
5030
<a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="n">all_models</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">ModelInfo</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
5031
<a id="__codelineno-0-50" name="__codelineno-0-50"></a>
5032
<a id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">info</span> <span class="ow">in</span> <span class="n">ProviderRegistry</span><span class="o">.</span><span class="n">all_registered</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
5033
<a id="__codelineno-0-52" name="__codelineno-0-52"></a> <span class="n">env_var</span> <span class="o">=</span> <span class="n">info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;env_var&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
5034
<a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="n">provider_class</span> <span class="o">=</span> <span class="n">info</span><span class="p">[</span><span class="s2">&quot;class&quot;</span><span class="p">]</span>
5035
<a id="__codelineno-0-54" name="__codelineno-0-54"></a>
5036
<a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s2">&quot;ollama&quot;</span><span class="p">:</span>
5037
<a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="c1"># Ollama: no API key, check server availability</span>
5038
<a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="k">try</span><span class="p">:</span>
5039
<a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="k">if</span> <span class="n">provider_class</span><span class="o">.</span><span class="n">is_available</span><span class="p">():</span>
5040
<a id="__codelineno-0-59" name="__codelineno-0-59"></a> <span class="n">provider</span> <span class="o">=</span> <span class="n">provider_class</span><span class="p">()</span>
5041
<a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="n">models</span> <span class="o">=</span> <span class="n">provider</span><span class="o">.</span><span class="n">list_models</span><span class="p">()</span>
5042
<a id="__codelineno-0-61" name="__codelineno-0-61"></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;Discovered </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">models</span><span class="p">)</span><span class="si">}</span><span class="s2"> Ollama models&quot;</span><span class="p">)</span>
5043
<a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="n">all_models</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">models</span><span class="p">)</span>
5044
<a id="__codelineno-0-63" name="__codelineno-0-63"></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>
5045
<a id="__codelineno-0-64" name="__codelineno-0-64"></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;Ollama discovery skipped: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5046
<a id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="k">continue</span>
5047
<a id="__codelineno-0-66" name="__codelineno-0-66"></a>
5048
<a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="c1"># For key-based providers, check the api_keys dict first, then env var</span>
5049
<a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="n">key</span> <span class="o">=</span> <span class="n">keys</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
5050
<a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">key</span> <span class="ow">and</span> <span class="n">env_var</span><span class="p">:</span>
5051
<a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="n">key</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="n">env_var</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
5052
<a id="__codelineno-0-71" name="__codelineno-0-71"></a>
5053
<a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="c1"># Special case: Gemini also supports service account credentials</span>
5054
<a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="n">gemini_creds</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
5055
<a id="__codelineno-0-74" name="__codelineno-0-74"></a> <span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s2">&quot;gemini&quot;</span><span class="p">:</span>
5056
<a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="n">gemini_creds</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&quot;GOOGLE_APPLICATION_CREDENTIALS&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
5057
<a id="__codelineno-0-76" name="__codelineno-0-76"></a>
5058
<a id="__codelineno-0-77" name="__codelineno-0-77"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">key</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">gemini_creds</span><span class="p">:</span>
5059
<a id="__codelineno-0-78" name="__codelineno-0-78"></a> <span class="k">continue</span>
5060
<a id="__codelineno-0-79" name="__codelineno-0-79"></a>
5061
<a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="k">try</span><span class="p">:</span>
5062
<a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="c1"># Handle provider-specific constructor args</span>
5063
<a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s2">&quot;gemini&quot;</span><span class="p">:</span>
5064
<a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="n">provider</span> <span class="o">=</span> <span class="n">provider_class</span><span class="p">(</span>
5065
<a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="n">api_key</span><span class="o">=</span><span class="n">key</span> <span class="ow">or</span> <span class="kc">None</span><span class="p">,</span>
5066
<a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="n">credentials_path</span><span class="o">=</span><span class="n">gemini_creds</span> <span class="ow">or</span> <span class="kc">None</span><span class="p">,</span>
5067
<a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="p">)</span>
5068
<a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="k">else</span><span class="p">:</span>
5069
<a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="n">provider</span> <span class="o">=</span> <span class="n">provider_class</span><span class="p">(</span><span class="n">api_key</span><span class="o">=</span><span class="n">key</span><span class="p">)</span>
5070
<a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="n">models</span> <span class="o">=</span> <span class="n">provider</span><span class="o">.</span><span class="n">list_models</span><span class="p">()</span>
5071
<a id="__codelineno-0-90" name="__codelineno-0-90"></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;Discovered </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">models</span><span class="p">)</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">name</span><span class="o">.</span><span class="n">capitalize</span><span class="p">()</span><span class="si">}</span><span class="s2"> models&quot;</span><span class="p">)</span>
5072
<a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="n">all_models</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">models</span><span class="p">)</span>
5073
<a id="__codelineno-0-92" name="__codelineno-0-92"></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>
5074
<a id="__codelineno-0-93" name="__codelineno-0-93"></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;</span><span class="si">{</span><span class="n">name</span><span class="o">.</span><span class="n">capitalize</span><span class="p">()</span><span class="si">}</span><span class="s2"> discovery skipped: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5075
<a id="__codelineno-0-94" name="__codelineno-0-94"></a>
5076
<a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="c1"># Sort by provider then id</span>
5077
<a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="n">all_models</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">provider</span><span class="p">,</span> <span class="n">m</span><span class="o">.</span><span class="n">id</span><span class="p">))</span>
5078
<a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="n">_cached_models</span> <span class="o">=</span> <span class="n">all_models</span>
5079
<a id="__codelineno-0-98" name="__codelineno-0-98"></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;Total discovered models: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">all_models</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5080
<a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="k">return</span> <span class="n">all_models</span>
5081
</code></pre></div></td></tr></table></div>
5082
</details>
5083
</div>
5084
5085
</div>
5086
5087
5088
5089
</div>
5090
5091
</div>
5092
5093
</div><hr />
5094
<h2 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">&para;</a></h2>
5095
<p>The provider system abstracts LLM API calls behind a unified interface. It supports multiple providers (OpenAI, Anthropic, Gemini, Ollama, and OpenAI-compatible services), automatic model discovery, capability-based routing, and usage tracking.</p>
5096
<p><strong>Key components:</strong></p>
5097
<ul>
5098
<li><strong><code>BaseProvider</code></strong> -- abstract interface that all providers implement</li>
5099
<li><strong><code>ProviderRegistry</code></strong> -- global registry mapping provider names to classes</li>
5100
<li><strong><code>ProviderManager</code></strong> -- high-level router that picks the best provider for each task</li>
5101
<li><strong><code>discover_available_models()</code></strong> -- scans all configured providers for available models</li>
5102
</ul>
5103
<hr />
5104
<h2 id="baseprovider-abc">BaseProvider (ABC)<a class="headerlink" href="#baseprovider-abc" title="Permanent link">&para;</a></h2>
5105
<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.providers.base</span><span class="w"> </span><span class="kn">import</span> <span class="n">BaseProvider</span>
5106
</code></pre></div>
5107
<p>Abstract base class that all provider implementations must subclass. Defines the four core capabilities: chat, vision, audio transcription, and model listing.</p>
5108
<p><strong>Class attribute:</strong></p>
5109
<table>
5110
<thead>
5111
<tr>
5112
<th>Attribute</th>
5113
<th>Type</th>
5114
<th>Description</th>
5115
</tr>
5116
</thead>
5117
<tbody>
5118
<tr>
5119
<td><code>provider_name</code></td>
5120
<td><code>str</code></td>
5121
<td>Identifier for this provider (e.g., <code>"openai"</code>, <code>"anthropic"</code>)</td>
5122
</tr>
5123
</tbody>
5124
</table>
5125
<h3 id="chat">chat()<a class="headerlink" href="#chat" title="Permanent link">&para;</a></h3>
5126
<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="nf">chat</span><span class="p">(</span>
5127
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a> <span class="bp">self</span><span class="p">,</span>
5128
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a> <span class="n">messages</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">dict</span><span class="p">],</span>
5129
<a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
5130
<a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a> <span class="n">temperature</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.7</span><span class="p">,</span>
5131
<a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5132
<a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span>
5133
</code></pre></div>
5134
<p>Send a chat completion request.</p>
5135
<p><strong>Parameters:</strong></p>
5136
<table>
5137
<thead>
5138
<tr>
5139
<th>Parameter</th>
5140
<th>Type</th>
5141
<th>Default</th>
5142
<th>Description</th>
5143
</tr>
5144
</thead>
5145
<tbody>
5146
<tr>
5147
<td><code>messages</code></td>
5148
<td><code>list[dict]</code></td>
5149
<td><em>required</em></td>
5150
<td>OpenAI-format message list (<code>role</code>, <code>content</code>)</td>
5151
</tr>
5152
<tr>
5153
<td><code>max_tokens</code></td>
5154
<td><code>int</code></td>
5155
<td><code>4096</code></td>
5156
<td>Maximum tokens in the response</td>
5157
</tr>
5158
<tr>
5159
<td><code>temperature</code></td>
5160
<td><code>float</code></td>
5161
<td><code>0.7</code></td>
5162
<td>Sampling temperature</td>
5163
</tr>
5164
<tr>
5165
<td><code>model</code></td>
5166
<td><code>Optional[str]</code></td>
5167
<td><code>None</code></td>
5168
<td>Override model ID</td>
5169
</tr>
5170
</tbody>
5171
</table>
5172
<p><strong>Returns:</strong> <code>str</code> -- the assistant's text response.</p>
5173
<h3 id="analyze_image">analyze_image()<a class="headerlink" href="#analyze_image" title="Permanent link">&para;</a></h3>
5174
<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">analyze_image</span><span class="p">(</span>
5175
<a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a> <span class="bp">self</span><span class="p">,</span>
5176
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a> <span class="n">image_bytes</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span>
5177
<a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a> <span class="n">prompt</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
5178
<a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
5179
<a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5180
<a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span>
5181
</code></pre></div>
5182
<p>Analyze an image with a text prompt using a vision-capable model.</p>
5183
<p><strong>Parameters:</strong></p>
5184
<table>
5185
<thead>
5186
<tr>
5187
<th>Parameter</th>
5188
<th>Type</th>
5189
<th>Default</th>
5190
<th>Description</th>
5191
</tr>
5192
</thead>
5193
<tbody>
5194
<tr>
5195
<td><code>image_bytes</code></td>
5196
<td><code>bytes</code></td>
5197
<td><em>required</em></td>
5198
<td>Raw image data (JPEG, PNG, etc.)</td>
5199
</tr>
5200
<tr>
5201
<td><code>prompt</code></td>
5202
<td><code>str</code></td>
5203
<td><em>required</em></td>
5204
<td>Analysis instructions</td>
5205
</tr>
5206
<tr>
5207
<td><code>max_tokens</code></td>
5208
<td><code>int</code></td>
5209
<td><code>4096</code></td>
5210
<td>Maximum tokens in the response</td>
5211
</tr>
5212
<tr>
5213
<td><code>model</code></td>
5214
<td><code>Optional[str]</code></td>
5215
<td><code>None</code></td>
5216
<td>Override model ID</td>
5217
</tr>
5218
</tbody>
5219
</table>
5220
<p><strong>Returns:</strong> <code>str</code> -- the assistant's analysis text.</p>
5221
<h3 id="transcribe_audio">transcribe_audio()<a class="headerlink" href="#transcribe_audio" title="Permanent link">&para;</a></h3>
5222
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">transcribe_audio</span><span class="p">(</span>
5223
<a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a> <span class="bp">self</span><span class="p">,</span>
5224
<a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a> <span class="n">audio_path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Path</span><span class="p">,</span>
5225
<a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a> <span class="n">language</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5226
<a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a> <span class="n">model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5227
<a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span>
5228
</code></pre></div>
5229
<p>Transcribe an audio file.</p>
5230
<p><strong>Parameters:</strong></p>
5231
<table>
5232
<thead>
5233
<tr>
5234
<th>Parameter</th>
5235
<th>Type</th>
5236
<th>Default</th>
5237
<th>Description</th>
5238
</tr>
5239
</thead>
5240
<tbody>
5241
<tr>
5242
<td><code>audio_path</code></td>
5243
<td><code>str \| Path</code></td>
5244
<td><em>required</em></td>
5245
<td>Path to the audio file</td>
5246
</tr>
5247
<tr>
5248
<td><code>language</code></td>
5249
<td><code>Optional[str]</code></td>
5250
<td><code>None</code></td>
5251
<td>Language hint (ISO 639-1 code)</td>
5252
</tr>
5253
<tr>
5254
<td><code>model</code></td>
5255
<td><code>Optional[str]</code></td>
5256
<td><code>None</code></td>
5257
<td>Override model ID</td>
5258
</tr>
5259
</tbody>
5260
</table>
5261
<p><strong>Returns:</strong> <code>dict</code> -- transcription result with keys <code>text</code>, <code>segments</code>, <code>duration</code>, etc.</p>
5262
<h3 id="list_models">list_models()<a class="headerlink" href="#list_models" title="Permanent link">&para;</a></h3>
5263
<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">list_models</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ModelInfo</span><span class="p">]</span>
5264
</code></pre></div>
5265
<p>Discover available models from this provider's API.</p>
5266
<p><strong>Returns:</strong> <code>list[ModelInfo]</code> -- available models with capability metadata.</p>
5267
<hr />
5268
<h2 id="modelinfo">ModelInfo<a class="headerlink" href="#modelinfo" title="Permanent link">&para;</a></h2>
5269
<div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.providers.base</span><span class="w"> </span><span class="kn">import</span> <span class="n">ModelInfo</span>
5270
</code></pre></div>
5271
<p>Pydantic model describing an available model from a provider.</p>
5272
<table>
5273
<thead>
5274
<tr>
5275
<th>Field</th>
5276
<th>Type</th>
5277
<th>Default</th>
5278
<th>Description</th>
5279
</tr>
5280
</thead>
5281
<tbody>
5282
<tr>
5283
<td><code>id</code></td>
5284
<td><code>str</code></td>
5285
<td><em>required</em></td>
5286
<td>Model identifier (e.g., <code>"gpt-4o"</code>, <code>"claude-haiku-4-5-20251001"</code>)</td>
5287
</tr>
5288
<tr>
5289
<td><code>provider</code></td>
5290
<td><code>str</code></td>
5291
<td><em>required</em></td>
5292
<td>Provider name (e.g., <code>"openai"</code>, <code>"anthropic"</code>, <code>"gemini"</code>)</td>
5293
</tr>
5294
<tr>
5295
<td><code>display_name</code></td>
5296
<td><code>str</code></td>
5297
<td><code>""</code></td>
5298
<td>Human-readable display name</td>
5299
</tr>
5300
<tr>
5301
<td><code>capabilities</code></td>
5302
<td><code>List[str]</code></td>
5303
<td><code>[]</code></td>
5304
<td>Model capabilities: <code>"chat"</code>, <code>"vision"</code>, <code>"audio"</code>, <code>"embedding"</code></td>
5305
</tr>
5306
</tbody>
5307
</table>
5308
<div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="p">{</span>
5309
<a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="w"> </span><span class="nt">&quot;id&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;gpt-4o&quot;</span><span class="p">,</span>
5310
<a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="w"> </span><span class="nt">&quot;provider&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;openai&quot;</span><span class="p">,</span>
5311
<a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a><span class="w"> </span><span class="nt">&quot;display_name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;GPT-4o&quot;</span><span class="p">,</span>
5312
<a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a><span class="w"> </span><span class="nt">&quot;capabilities&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;chat&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;vision&quot;</span><span class="p">]</span>
5313
<a id="__codelineno-6-6" name="__codelineno-6-6" href="#__codelineno-6-6"></a><span class="p">}</span>
5314
</code></pre></div>
5315
<hr />
5316
<h2 id="providerregistry">ProviderRegistry<a class="headerlink" href="#providerregistry" title="Permanent link">&para;</a></h2>
5317
<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">video_processor.providers.base</span><span class="w"> </span><span class="kn">import</span> <span class="n">ProviderRegistry</span>
5318
</code></pre></div>
5319
<p>Class-level registry for provider classes. Providers register themselves with metadata on import. This registry is used internally by <code>ProviderManager</code> but can also be used directly for introspection.</p>
5320
<h3 id="register">register()<a class="headerlink" href="#register" title="Permanent link">&para;</a></h3>
5321
<div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="nd">@classmethod</span>
5322
<a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="k">def</span><span class="w"> </span><span class="nf">register</span><span class="p">(</span>
5323
<a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a> <span class="bp">cls</span><span class="p">,</span>
5324
<a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
5325
<a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a> <span class="n">provider_class</span><span class="p">:</span> <span class="nb">type</span><span class="p">,</span>
5326
<a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a> <span class="n">env_var</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
5327
<a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a> <span class="n">model_prefixes</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="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5328
<a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a> <span class="n">default_models</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5329
<a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span>
5330
</code></pre></div>
5331
<p>Register a provider class with its metadata. Called by each provider module at import time.</p>
5332
<p><strong>Parameters:</strong></p>
5333
<table>
5334
<thead>
5335
<tr>
5336
<th>Parameter</th>
5337
<th>Type</th>
5338
<th>Default</th>
5339
<th>Description</th>
5340
</tr>
5341
</thead>
5342
<tbody>
5343
<tr>
5344
<td><code>name</code></td>
5345
<td><code>str</code></td>
5346
<td><em>required</em></td>
5347
<td>Provider name (e.g., <code>"openai"</code>)</td>
5348
</tr>
5349
<tr>
5350
<td><code>provider_class</code></td>
5351
<td><code>type</code></td>
5352
<td><em>required</em></td>
5353
<td>The provider class</td>
5354
</tr>
5355
<tr>
5356
<td><code>env_var</code></td>
5357
<td><code>str</code></td>
5358
<td><code>""</code></td>
5359
<td>Environment variable for API key</td>
5360
</tr>
5361
<tr>
5362
<td><code>model_prefixes</code></td>
5363
<td><code>Optional[List[str]]</code></td>
5364
<td><code>None</code></td>
5365
<td>Model ID prefixes for auto-detection (e.g., <code>["gpt-", "o1-"]</code>)</td>
5366
</tr>
5367
<tr>
5368
<td><code>default_models</code></td>
5369
<td><code>Optional[Dict[str, str]]</code></td>
5370
<td><code>None</code></td>
5371
<td>Default models per capability (e.g., <code>{"chat": "gpt-4o", "vision": "gpt-4o"}</code>)</td>
5372
</tr>
5373
</tbody>
5374
</table>
5375
<h3 id="get">get()<a class="headerlink" href="#get" title="Permanent link">&para;</a></h3>
5376
<div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="nd">@classmethod</span>
5377
<a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">type</span>
5378
</code></pre></div>
5379
<p>Return the provider class for a given name. Raises <code>ValueError</code> if the provider is not registered.</p>
5380
<h3 id="get_by_model">get_by_model()<a class="headerlink" href="#get_by_model" title="Permanent link">&para;</a></h3>
5381
<div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="nd">@classmethod</span>
5382
<a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_by_model</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">model_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
5383
</code></pre></div>
5384
<p>Return the provider name for a model ID based on prefix matching. Returns <code>None</code> if no match is found.</p>
5385
<h3 id="get_default_models">get_default_models()<a class="headerlink" href="#get_default_models" title="Permanent link">&para;</a></h3>
5386
<div class="highlight"><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="nd">@classmethod</span>
5387
<a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_default_models</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span>
5388
</code></pre></div>
5389
<p>Return the default models dict for a provider, mapping capability names to model IDs.</p>
5390
<h3 id="available">available()<a class="headerlink" href="#available" title="Permanent link">&para;</a></h3>
5391
<div class="highlight"><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="nd">@classmethod</span>
5392
<a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="k">def</span><span class="w"> </span><span class="nf">available</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
5393
</code></pre></div>
5394
<p>Return names of providers whose required environment variable is set (or providers with no env var requirement, like Ollama).</p>
5395
<h3 id="all_registered">all_registered()<a class="headerlink" href="#all_registered" title="Permanent link">&para;</a></h3>
5396
<div class="highlight"><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="nd">@classmethod</span>
5397
<a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a><span class="k">def</span><span class="w"> </span><span class="nf">all_registered</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Dict</span><span class="p">]</span>
5398
</code></pre></div>
5399
<p>Return all registered providers and their metadata dictionaries.</p>
5400
<hr />
5401
<h2 id="openaicompatibleprovider">OpenAICompatibleProvider<a class="headerlink" href="#openaicompatibleprovider" title="Permanent link">&para;</a></h2>
5402
<div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.providers.base</span><span class="w"> </span><span class="kn">import</span> <span class="n">OpenAICompatibleProvider</span>
5403
</code></pre></div>
5404
<p>Base class for providers using OpenAI-compatible APIs (Together, Fireworks, Cerebras, xAI, Azure). Implements <code>chat()</code>, <code>analyze_image()</code>, and <code>list_models()</code> using the OpenAI client library. <code>transcribe_audio()</code> raises <code>NotImplementedError</code> by default.</p>
5405
<p><strong>Constructor:</strong></p>
5406
<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="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">api_key</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">base_url</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span>
5407
</code></pre></div>
5408
<table>
5409
<thead>
5410
<tr>
5411
<th>Parameter</th>
5412
<th>Type</th>
5413
<th>Default</th>
5414
<th>Description</th>
5415
</tr>
5416
</thead>
5417
<tbody>
5418
<tr>
5419
<td><code>api_key</code></td>
5420
<td><code>Optional[str]</code></td>
5421
<td><code>None</code></td>
5422
<td>API key (falls back to <code>self.env_var</code> environment variable)</td>
5423
</tr>
5424
<tr>
5425
<td><code>base_url</code></td>
5426
<td><code>Optional[str]</code></td>
5427
<td><code>None</code></td>
5428
<td>API base URL (falls back to <code>self.base_url</code> class attribute)</td>
5429
</tr>
5430
</tbody>
5431
</table>
5432
<p><strong>Subclass attributes to override:</strong></p>
5433
<table>
5434
<thead>
5435
<tr>
5436
<th>Attribute</th>
5437
<th>Description</th>
5438
</tr>
5439
</thead>
5440
<tbody>
5441
<tr>
5442
<td><code>provider_name</code></td>
5443
<td>Provider identifier string</td>
5444
</tr>
5445
<tr>
5446
<td><code>base_url</code></td>
5447
<td>Default API base URL</td>
5448
</tr>
5449
<tr>
5450
<td><code>env_var</code></td>
5451
<td>Environment variable name for the API key</td>
5452
</tr>
5453
</tbody>
5454
</table>
5455
<p><strong>Usage tracking:</strong> After each <code>chat()</code> or <code>analyze_image()</code> call, the provider stores token counts in <code>self._last_usage</code> as <code>{"input_tokens": int, "output_tokens": int}</code>. This is consumed by <code>ProviderManager._track()</code>.</p>
5456
<hr />
5457
<h2 id="providermanager">ProviderManager<a class="headerlink" href="#providermanager" title="Permanent link">&para;</a></h2>
5458
<div class="highlight"><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></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>
5459
</code></pre></div>
5460
<p>High-level router that selects the best available provider and model for each API call. Supports explicit model selection, forced provider, or automatic selection based on discovered capabilities.</p>
5461
<h3 id="constructor">Constructor<a class="headerlink" href="#constructor" title="Permanent link">&para;</a></h3>
5462
<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="fm">__init__</span><span class="p">(</span>
5463
<a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a> <span class="bp">self</span><span class="p">,</span>
5464
<a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a> <span class="n">vision_model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5465
<a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a> <span class="n">chat_model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5466
<a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a> <span class="n">transcription_model</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5467
<a id="__codelineno-17-6" name="__codelineno-17-6" href="#__codelineno-17-6"></a> <span class="n">provider</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5468
<a id="__codelineno-17-7" name="__codelineno-17-7" href="#__codelineno-17-7"></a> <span class="n">auto</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
5469
<a id="__codelineno-17-8" name="__codelineno-17-8" href="#__codelineno-17-8"></a><span class="p">)</span>
5470
</code></pre></div>
5471
<table>
5472
<thead>
5473
<tr>
5474
<th>Parameter</th>
5475
<th>Type</th>
5476
<th>Default</th>
5477
<th>Description</th>
5478
</tr>
5479
</thead>
5480
<tbody>
5481
<tr>
5482
<td><code>vision_model</code></td>
5483
<td><code>Optional[str]</code></td>
5484
<td><code>None</code></td>
5485
<td>Override model for vision tasks (e.g., <code>"gpt-4o"</code>)</td>
5486
</tr>
5487
<tr>
5488
<td><code>chat_model</code></td>
5489
<td><code>Optional[str]</code></td>
5490
<td><code>None</code></td>
5491
<td>Override model for chat/LLM tasks</td>
5492
</tr>
5493
<tr>
5494
<td><code>transcription_model</code></td>
5495
<td><code>Optional[str]</code></td>
5496
<td><code>None</code></td>
5497
<td>Override model for transcription</td>
5498
</tr>
5499
<tr>
5500
<td><code>provider</code></td>
5501
<td><code>Optional[str]</code></td>
5502
<td><code>None</code></td>
5503
<td>Force all tasks to a single provider</td>
5504
</tr>
5505
<tr>
5506
<td><code>auto</code></td>
5507
<td><code>bool</code></td>
5508
<td><code>True</code></td>
5509
<td>If <code>True</code> and no model specified, pick the best available</td>
5510
</tr>
5511
</tbody>
5512
</table>
5513
<p><strong>Attributes:</strong></p>
5514
<table>
5515
<thead>
5516
<tr>
5517
<th>Attribute</th>
5518
<th>Type</th>
5519
<th>Description</th>
5520
</tr>
5521
</thead>
5522
<tbody>
5523
<tr>
5524
<td><code>usage</code></td>
5525
<td><code>UsageTracker</code></td>
5526
<td>Tracks token counts and API costs across all calls</td>
5527
</tr>
5528
</tbody>
5529
</table>
5530
<h3 id="auto-selection-preferences">Auto-selection preferences<a class="headerlink" href="#auto-selection-preferences" title="Permanent link">&para;</a></h3>
5531
<p>When <code>auto=True</code> and no explicit model is set, providers are tried in this order:</p>
5532
<p><strong>Vision:</strong> Gemini (<code>gemini-2.5-flash</code>) &gt; OpenAI (<code>gpt-4o-mini</code>) &gt; Anthropic (<code>claude-haiku-4-5-20251001</code>)</p>
5533
<p><strong>Chat:</strong> Anthropic (<code>claude-haiku-4-5-20251001</code>) &gt; OpenAI (<code>gpt-4o-mini</code>) &gt; Gemini (<code>gemini-2.5-flash</code>)</p>
5534
<p><strong>Transcription:</strong> OpenAI (<code>whisper-1</code>) &gt; Gemini (<code>gemini-2.5-flash</code>)</p>
5535
<p>If no API-key-based provider is available, Ollama is tried as a fallback.</p>
5536
<h3 id="chat_1">chat()<a class="headerlink" href="#chat_1" title="Permanent link">&para;</a></h3>
5537
<div class="highlight"><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">chat</span><span class="p">(</span>
5538
<a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a> <span class="bp">self</span><span class="p">,</span>
5539
<a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a> <span class="n">messages</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">dict</span><span class="p">],</span>
5540
<a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
5541
<a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a> <span class="n">temperature</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.7</span><span class="p">,</span>
5542
<a id="__codelineno-18-6" name="__codelineno-18-6" href="#__codelineno-18-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span>
5543
</code></pre></div>
5544
<p>Send a chat completion to the best available provider. Automatically resolves which provider and model to use.</p>
5545
<p><strong>Parameters:</strong></p>
5546
<table>
5547
<thead>
5548
<tr>
5549
<th>Parameter</th>
5550
<th>Type</th>
5551
<th>Default</th>
5552
<th>Description</th>
5553
</tr>
5554
</thead>
5555
<tbody>
5556
<tr>
5557
<td><code>messages</code></td>
5558
<td><code>list[dict]</code></td>
5559
<td><em>required</em></td>
5560
<td>OpenAI-format messages</td>
5561
</tr>
5562
<tr>
5563
<td><code>max_tokens</code></td>
5564
<td><code>int</code></td>
5565
<td><code>4096</code></td>
5566
<td>Maximum response tokens</td>
5567
</tr>
5568
<tr>
5569
<td><code>temperature</code></td>
5570
<td><code>float</code></td>
5571
<td><code>0.7</code></td>
5572
<td>Sampling temperature</td>
5573
</tr>
5574
</tbody>
5575
</table>
5576
<p><strong>Returns:</strong> <code>str</code> -- assistant response text.</p>
5577
<p><strong>Raises:</strong> <code>RuntimeError</code> if no provider is available for the <code>chat</code> capability.</p>
5578
<h3 id="analyze_image_1">analyze_image()<a class="headerlink" href="#analyze_image_1" title="Permanent link">&para;</a></h3>
5579
<div class="highlight"><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">analyze_image</span><span class="p">(</span>
5580
<a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a> <span class="bp">self</span><span class="p">,</span>
5581
<a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a> <span class="n">image_bytes</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span>
5582
<a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a> <span class="n">prompt</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
5583
<a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a> <span class="n">max_tokens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">,</span>
5584
<a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span>
5585
</code></pre></div>
5586
<p>Analyze an image using the best available vision provider.</p>
5587
<p><strong>Returns:</strong> <code>str</code> -- analysis text.</p>
5588
<p><strong>Raises:</strong> <code>RuntimeError</code> if no provider is available for the <code>vision</code> capability.</p>
5589
<h3 id="transcribe_audio_1">transcribe_audio()<a class="headerlink" href="#transcribe_audio_1" title="Permanent link">&para;</a></h3>
5590
<div class="highlight"><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">transcribe_audio</span><span class="p">(</span>
5591
<a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a> <span class="bp">self</span><span class="p">,</span>
5592
<a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a> <span class="n">audio_path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Path</span><span class="p">,</span>
5593
<a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a> <span class="n">language</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5594
<a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a> <span class="n">speaker_hints</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5595
<a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span>
5596
</code></pre></div>
5597
<p>Transcribe audio. Prefers local Whisper (no file size limits, no API costs) when available, falling back to API-based transcription.</p>
5598
<p><strong>Parameters:</strong></p>
5599
<table>
5600
<thead>
5601
<tr>
5602
<th>Parameter</th>
5603
<th>Type</th>
5604
<th>Default</th>
5605
<th>Description</th>
5606
</tr>
5607
</thead>
5608
<tbody>
5609
<tr>
5610
<td><code>audio_path</code></td>
5611
<td><code>str \| Path</code></td>
5612
<td><em>required</em></td>
5613
<td>Path to the audio file</td>
5614
</tr>
5615
<tr>
5616
<td><code>language</code></td>
5617
<td><code>Optional[str]</code></td>
5618
<td><code>None</code></td>
5619
<td>Language hint</td>
5620
</tr>
5621
<tr>
5622
<td><code>speaker_hints</code></td>
5623
<td><code>Optional[list[str]]</code></td>
5624
<td><code>None</code></td>
5625
<td>Speaker names for better recognition</td>
5626
</tr>
5627
</tbody>
5628
</table>
5629
<p><strong>Returns:</strong> <code>dict</code> -- transcription result with <code>text</code>, <code>segments</code>, <code>duration</code>.</p>
5630
<p><strong>Local Whisper:</strong> If <code>transcription_model</code> is unset or starts with <code>"whisper-local"</code>, the manager tries local Whisper first. Use <code>"whisper-local:large"</code> to specify a model size.</p>
5631
<h3 id="get_models_used">get_models_used()<a class="headerlink" href="#get_models_used" title="Permanent link">&para;</a></h3>
5632
<div class="highlight"><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_models_used</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span>
5633
</code></pre></div>
5634
<p>Return a dict mapping capability to <code>"provider/model"</code> string for tracking purposes.</p>
5635
<div class="highlight"><pre><span></span><code><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="n">pm</span> <span class="o">=</span> <span class="n">ProviderManager</span><span class="p">()</span>
5636
<a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a><span class="nb">print</span><span class="p">(</span><span class="n">pm</span><span class="o">.</span><span class="n">get_models_used</span><span class="p">())</span>
5637
<a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a><span class="c1"># {&quot;vision&quot;: &quot;gemini/gemini-2.5-flash&quot;, &quot;chat&quot;: &quot;anthropic/claude-haiku-4-5-20251001&quot;, ...}</span>
5638
</code></pre></div>
5639
<h3 id="usage-examples">Usage examples<a class="headerlink" href="#usage-examples" title="Permanent link">&para;</a></h3>
5640
<div class="highlight"><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></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>
5641
<a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a>
5642
<a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="c1"># Auto-select best providers</span>
5643
<a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-4"></a><span class="n">pm</span> <span class="o">=</span> <span class="n">ProviderManager</span><span class="p">()</span>
5644
<a id="__codelineno-23-5" name="__codelineno-23-5" href="#__codelineno-23-5"></a>
5645
<a id="__codelineno-23-6" name="__codelineno-23-6" href="#__codelineno-23-6"></a><span class="c1"># Force everything through one provider</span>
5646
<a id="__codelineno-23-7" name="__codelineno-23-7" href="#__codelineno-23-7"></a><span class="n">pm</span> <span class="o">=</span> <span class="n">ProviderManager</span><span class="p">(</span><span class="n">provider</span><span class="o">=</span><span class="s2">&quot;openai&quot;</span><span class="p">)</span>
5647
<a id="__codelineno-23-8" name="__codelineno-23-8" href="#__codelineno-23-8"></a>
5648
<a id="__codelineno-23-9" name="__codelineno-23-9" href="#__codelineno-23-9"></a><span class="c1"># Explicit model selection</span>
5649
<a id="__codelineno-23-10" name="__codelineno-23-10" href="#__codelineno-23-10"></a><span class="n">pm</span> <span class="o">=</span> <span class="n">ProviderManager</span><span class="p">(</span>
5650
<a id="__codelineno-23-11" name="__codelineno-23-11" href="#__codelineno-23-11"></a> <span class="n">vision_model</span><span class="o">=</span><span class="s2">&quot;gpt-4o&quot;</span><span class="p">,</span>
5651
<a id="__codelineno-23-12" name="__codelineno-23-12" href="#__codelineno-23-12"></a> <span class="n">chat_model</span><span class="o">=</span><span class="s2">&quot;claude-haiku-4-5-20251001&quot;</span><span class="p">,</span>
5652
<a id="__codelineno-23-13" name="__codelineno-23-13" href="#__codelineno-23-13"></a> <span class="n">transcription_model</span><span class="o">=</span><span class="s2">&quot;whisper-local:large&quot;</span><span class="p">,</span>
5653
<a id="__codelineno-23-14" name="__codelineno-23-14" href="#__codelineno-23-14"></a><span class="p">)</span>
5654
<a id="__codelineno-23-15" name="__codelineno-23-15" href="#__codelineno-23-15"></a>
5655
<a id="__codelineno-23-16" name="__codelineno-23-16" href="#__codelineno-23-16"></a><span class="c1"># Chat completion</span>
5656
<a id="__codelineno-23-17" name="__codelineno-23-17" href="#__codelineno-23-17"></a><span class="n">response</span> <span class="o">=</span> <span class="n">pm</span><span class="o">.</span><span class="n">chat</span><span class="p">([</span>
5657
<a id="__codelineno-23-18" name="__codelineno-23-18" href="#__codelineno-23-18"></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="s2">&quot;Summarize this meeting transcript...&quot;</span><span class="p">}</span>
5658
<a id="__codelineno-23-19" name="__codelineno-23-19" href="#__codelineno-23-19"></a><span class="p">])</span>
5659
<a id="__codelineno-23-20" name="__codelineno-23-20" href="#__codelineno-23-20"></a>
5660
<a id="__codelineno-23-21" name="__codelineno-23-21" href="#__codelineno-23-21"></a><span class="c1"># Image analysis</span>
5661
<a id="__codelineno-23-22" name="__codelineno-23-22" href="#__codelineno-23-22"></a><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&quot;diagram.png&quot;</span><span class="p">,</span> <span class="s2">&quot;rb&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
5662
<a id="__codelineno-23-23" name="__codelineno-23-23" href="#__codelineno-23-23"></a> <span class="n">analysis</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">f</span><span class="o">.</span><span class="n">read</span><span class="p">(),</span> <span class="s2">&quot;Describe this architecture diagram&quot;</span><span class="p">)</span>
5663
<a id="__codelineno-23-24" name="__codelineno-23-24" href="#__codelineno-23-24"></a>
5664
<a id="__codelineno-23-25" name="__codelineno-23-25" href="#__codelineno-23-25"></a><span class="c1"># Transcription with speaker hints</span>
5665
<a id="__codelineno-23-26" name="__codelineno-23-26" href="#__codelineno-23-26"></a><span class="n">result</span> <span class="o">=</span> <span class="n">pm</span><span class="o">.</span><span class="n">transcribe_audio</span><span class="p">(</span>
5666
<a id="__codelineno-23-27" name="__codelineno-23-27" href="#__codelineno-23-27"></a> <span class="s2">&quot;meeting.mp3&quot;</span><span class="p">,</span>
5667
<a id="__codelineno-23-28" name="__codelineno-23-28" href="#__codelineno-23-28"></a> <span class="n">language</span><span class="o">=</span><span class="s2">&quot;en&quot;</span><span class="p">,</span>
5668
<a id="__codelineno-23-29" name="__codelineno-23-29" href="#__codelineno-23-29"></a> <span class="n">speaker_hints</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Alice&quot;</span><span class="p">,</span> <span class="s2">&quot;Bob&quot;</span><span class="p">,</span> <span class="s2">&quot;Charlie&quot;</span><span class="p">],</span>
5669
<a id="__codelineno-23-30" name="__codelineno-23-30" href="#__codelineno-23-30"></a><span class="p">)</span>
5670
<a id="__codelineno-23-31" name="__codelineno-23-31" href="#__codelineno-23-31"></a>
5671
<a id="__codelineno-23-32" name="__codelineno-23-32" href="#__codelineno-23-32"></a><span class="c1"># Check usage</span>
5672
<a id="__codelineno-23-33" name="__codelineno-23-33" href="#__codelineno-23-33"></a><span class="nb">print</span><span class="p">(</span><span class="n">pm</span><span class="o">.</span><span class="n">usage</span><span class="o">.</span><span class="n">summary</span><span class="p">())</span>
5673
</code></pre></div>
5674
<hr />
5675
<h2 id="discover_available_models">discover_available_models()<a class="headerlink" href="#discover_available_models" title="Permanent link">&para;</a></h2>
5676
<div class="highlight"><pre><span></span><code><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.providers.discovery</span><span class="w"> </span><span class="kn">import</span> <span class="n">discover_available_models</span>
5677
</code></pre></div>
5678
<div class="highlight"><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">discover_available_models</span><span class="p">(</span>
5679
<a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a> <span class="n">api_keys</span><span class="p">:</span> <span class="n">Optional</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="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5680
<a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a> <span class="n">force_refresh</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
5681
<a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ModelInfo</span><span class="p">]</span>
5682
</code></pre></div>
5683
<p>Discover available models from all configured providers. For each provider with a valid API key, calls <code>list_models()</code> and returns a unified, sorted list.</p>
5684
<p><strong>Parameters:</strong></p>
5685
<table>
5686
<thead>
5687
<tr>
5688
<th>Parameter</th>
5689
<th>Type</th>
5690
<th>Default</th>
5691
<th>Description</th>
5692
</tr>
5693
</thead>
5694
<tbody>
5695
<tr>
5696
<td><code>api_keys</code></td>
5697
<td><code>Optional[dict[str, str]]</code></td>
5698
<td><code>None</code></td>
5699
<td>Override API keys (defaults to environment variables)</td>
5700
</tr>
5701
<tr>
5702
<td><code>force_refresh</code></td>
5703
<td><code>bool</code></td>
5704
<td><code>False</code></td>
5705
<td>Force re-discovery, ignoring the session cache</td>
5706
</tr>
5707
</tbody>
5708
</table>
5709
<p><strong>Returns:</strong> <code>list[ModelInfo]</code> -- all discovered models, sorted by provider then model ID.</p>
5710
<p><strong>Caching:</strong> Results are cached for the session. Use <code>force_refresh=True</code> or <code>clear_discovery_cache()</code> to refresh.</p>
5711
<div class="highlight"><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.providers.discovery</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
5712
<a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a> <span class="n">discover_available_models</span><span class="p">,</span>
5713
<a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a> <span class="n">clear_discovery_cache</span><span class="p">,</span>
5714
<a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a><span class="p">)</span>
5715
<a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-5"></a>
5716
<a id="__codelineno-26-6" name="__codelineno-26-6" href="#__codelineno-26-6"></a><span class="c1"># Discover models using environment variables</span>
5717
<a id="__codelineno-26-7" name="__codelineno-26-7" href="#__codelineno-26-7"></a><span class="n">models</span> <span class="o">=</span> <span class="n">discover_available_models</span><span class="p">()</span>
5718
<a id="__codelineno-26-8" name="__codelineno-26-8" href="#__codelineno-26-8"></a><span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">models</span><span class="p">:</span>
5719
<a id="__codelineno-26-9" name="__codelineno-26-9" href="#__codelineno-26-9"></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">m</span><span class="o">.</span><span class="n">provider</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">m</span><span class="o">.</span><span class="n">id</span><span class="si">}</span><span class="s2"> - </span><span class="si">{</span><span class="n">m</span><span class="o">.</span><span class="n">capabilities</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5720
<a id="__codelineno-26-10" name="__codelineno-26-10" href="#__codelineno-26-10"></a>
5721
<a id="__codelineno-26-11" name="__codelineno-26-11" href="#__codelineno-26-11"></a><span class="c1"># Force refresh</span>
5722
<a id="__codelineno-26-12" name="__codelineno-26-12" href="#__codelineno-26-12"></a><span class="n">models</span> <span class="o">=</span> <span class="n">discover_available_models</span><span class="p">(</span><span class="n">force_refresh</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
5723
<a id="__codelineno-26-13" name="__codelineno-26-13" href="#__codelineno-26-13"></a>
5724
<a id="__codelineno-26-14" name="__codelineno-26-14" href="#__codelineno-26-14"></a><span class="c1"># Override API keys</span>
5725
<a id="__codelineno-26-15" name="__codelineno-26-15" href="#__codelineno-26-15"></a><span class="n">models</span> <span class="o">=</span> <span class="n">discover_available_models</span><span class="p">(</span><span class="n">api_keys</span><span class="o">=</span><span class="p">{</span>
5726
<a id="__codelineno-26-16" name="__codelineno-26-16" href="#__codelineno-26-16"></a> <span class="s2">&quot;openai&quot;</span><span class="p">:</span> <span class="s2">&quot;sk-...&quot;</span><span class="p">,</span>
5727
<a id="__codelineno-26-17" name="__codelineno-26-17" href="#__codelineno-26-17"></a> <span class="s2">&quot;anthropic&quot;</span><span class="p">:</span> <span class="s2">&quot;sk-ant-...&quot;</span><span class="p">,</span>
5728
<a id="__codelineno-26-18" name="__codelineno-26-18" href="#__codelineno-26-18"></a><span class="p">})</span>
5729
<a id="__codelineno-26-19" name="__codelineno-26-19" href="#__codelineno-26-19"></a>
5730
<a id="__codelineno-26-20" name="__codelineno-26-20" href="#__codelineno-26-20"></a><span class="c1"># Clear cache</span>
5731
<a id="__codelineno-26-21" name="__codelineno-26-21" href="#__codelineno-26-21"></a><span class="n">clear_discovery_cache</span><span class="p">()</span>
5732
</code></pre></div>
5733
<h3 id="clear_discovery_cache">clear_discovery_cache()<a class="headerlink" href="#clear_discovery_cache" title="Permanent link">&para;</a></h3>
5734
<div class="highlight"><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">clear_discovery_cache</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kc">None</span>
5735
</code></pre></div>
5736
<p>Clear the cached model list, forcing the next <code>discover_available_models()</code> call to re-query providers.</p>
5737
<hr />
5738
<h2 id="built-in-providers">Built-in Providers<a class="headerlink" href="#built-in-providers" title="Permanent link">&para;</a></h2>
5739
<p>The following providers are registered automatically when the provider system initializes:</p>
5740
<table>
5741
<thead>
5742
<tr>
5743
<th>Provider</th>
5744
<th>Environment Variable</th>
5745
<th>Capabilities</th>
5746
<th>Default Chat Model</th>
5747
</tr>
5748
</thead>
5749
<tbody>
5750
<tr>
5751
<td><code>openai</code></td>
5752
<td><code>OPENAI_API_KEY</code></td>
5753
<td>chat, vision, audio</td>
5754
<td><code>gpt-4o-mini</code></td>
5755
</tr>
5756
<tr>
5757
<td><code>anthropic</code></td>
5758
<td><code>ANTHROPIC_API_KEY</code></td>
5759
<td>chat, vision</td>
5760
<td><code>claude-haiku-4-5-20251001</code></td>
5761
</tr>
5762
<tr>
5763
<td><code>gemini</code></td>
5764
<td><code>GEMINI_API_KEY</code></td>
5765
<td>chat, vision, audio</td>
5766
<td><code>gemini-2.5-flash</code></td>
5767
</tr>
5768
<tr>
5769
<td><code>ollama</code></td>
5770
<td><em>(none -- checks server)</em></td>
5771
<td>chat, vision</td>
5772
<td><em>(depends on installed models)</em></td>
5773
</tr>
5774
<tr>
5775
<td><code>together</code></td>
5776
<td><code>TOGETHER_API_KEY</code></td>
5777
<td>chat</td>
5778
<td><em>(varies)</em></td>
5779
</tr>
5780
<tr>
5781
<td><code>fireworks</code></td>
5782
<td><code>FIREWORKS_API_KEY</code></td>
5783
<td>chat</td>
5784
<td><em>(varies)</em></td>
5785
</tr>
5786
<tr>
5787
<td><code>cerebras</code></td>
5788
<td><code>CEREBRAS_API_KEY</code></td>
5789
<td>chat</td>
5790
<td><em>(varies)</em></td>
5791
</tr>
5792
<tr>
5793
<td><code>xai</code></td>
5794
<td><code>XAI_API_KEY</code></td>
5795
<td>chat</td>
5796
<td><em>(varies)</em></td>
5797
</tr>
5798
<tr>
5799
<td><code>azure</code></td>
5800
<td><code>AZURE_OPENAI_API_KEY</code></td>
5801
<td>chat, vision</td>
5802
<td><em>(varies)</em></td>
5803
</tr>
5804
</tbody>
5805
</table>
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
</article>
5820
</div>
5821
5822
5823
<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>
5824
5825
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
5826
</div>
5827
5828
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
5829
5830
<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>
5831
Back to top
5832
</button>
5833
5834
</main>
5835
5836
<footer class="md-footer">
5837
5838
<div class="md-footer-meta md-typeset">
5839
<div class="md-footer-meta__inner md-grid">
5840
<div class="md-copyright">
5841
5842
<div class="md-copyright__highlight">
5843
Copyright &copy; 2026 CONFLICT LLC
5844
</div>
5845
5846
5847
Made with
5848
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
5849
Material for MkDocs
5850
</a>
5851
5852
</div>
5853
5854
5855
<div class="md-social">
5856
5857
5858
5859
5860
5861
5862
5863
5864
<a href="https://github.com/ConflictHQ/PlanOpticon" target="_blank" rel="noopener" title="github.com" class="md-social__link">
5865
<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>
5866
</a>
5867
5868
</div>
5869
5870
</div>
5871
</div>
5872
</footer>
5873
5874
</div>
5875
<div class="md-dialog" data-md-component="dialog">
5876
<div class="md-dialog__inner md-typeset"></div>
5877
</div>
5878
5879
5880
5881
5882
5883
<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>
5884
5885
5886
<script src="../../assets/javascripts/bundle.79ae519e.min.js"></script>
5887
5888
5889
</body>
5890
</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