Skip to content

Commit f4dd1f2

Browse files
Wire VLM toggle + result badge across all tools (02-19 + obs)
Each tool now routes API calls through getVLMClient() so switching between Moondream and GPT-4o-mini in the toggle actually changes the engine used. Added vlm-result-badge.js script to all index.html files. Fixed containerSelector from .control-panel h2 to .app-header h1 so the toggle actually renders. Added VLMResultBadge.showCurrent(elapsed) after API results to show which engine produced the output. Tools 15 (Whisper) and 04b (Tesseract) only got the script tag since they don't make VLM calls. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
1 parent 60a269e commit f4dd1f2

File tree

38 files changed

+229
-57
lines changed

38 files changed

+229
-57
lines changed

02-detection-boxes/app.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ document.addEventListener('DOMContentLoaded', async function() {
2626
let isRunning = false;
2727
let detectionResults = {};
2828

29+
// VLM-aware client helper: routes through toggle when available
30+
function getVLMClient() {
31+
if (window.vlmToggle) return window.vlmToggle.getClient();
32+
return client;
33+
}
34+
2935
const DEFAULT_COLORS = ['#93CCEA', '#2A9D8F', '#E9C46A', '#E76F51', '#9B5DE5', '#F72585'];
3036

3137
const DEFAULT_OBJECTS = [
@@ -55,7 +61,7 @@ document.addEventListener('DOMContentLoaded', async function() {
5561

5662
// Initialize VLM Toggle
5763
window.vlmToggle = new VLMToggle({
58-
containerSelector: '.control-panel h2',
64+
containerSelector: '.app-header h1',
5965
toolId: 'detection-boxes',
6066
onChange: (engine) => {
6167
window.reasoningConsole.logInfo('Switched to ' + engine + ' VLM');
@@ -229,9 +235,10 @@ document.addEventListener('DOMContentLoaded', async function() {
229235
}
230236

231237
async function detectAll() {
232-
if (!client) {
238+
const activeClient = getVLMClient();
239+
if (!activeClient) {
233240
window.reasoningConsole.logError('No API key configured');
234-
updateStatus('Please configure your API key', true);
241+
updateStatus('Please configure an API key', true);
235242
window.apiKeyManager.showModal();
236243
return;
237244
}
@@ -252,7 +259,7 @@ document.addEventListener('DOMContentLoaded', async function() {
252259
try {
253260
const promises = enabledObjects.map(async (obj) => {
254261
try {
255-
const result = await client.detectInVideo(video, obj.name);
262+
const result = await activeClient.detectInVideo(video, obj.name);
256263
detectionResults[obj.name] = {
257264
objects: result.objects,
258265
color: obj.color
@@ -288,6 +295,7 @@ document.addEventListener('DOMContentLoaded', async function() {
288295
updateStatus(`No objects found (${elapsed}ms)`);
289296
}
290297

298+
VLMResultBadge.showCurrent(elapsed);
291299
} catch (error) {
292300
window.reasoningConsole.logError(error.message);
293301
updateStatus('Error: ' + error.message, true);

02-detection-boxes/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ <h4>Box Style</h4>
216216
<script src="../shared/video-source-adapter.js"></script>
217217
<script src="../shared/openai-client.js"></script>
218218
<script src="../shared/vlm-toggle.js"></script>
219+
<script src="../shared/vlm-result-badge.js"></script>
219220
<script src="app.js"></script>
220221
<script src="../shared/ux-utils.js"></script>
221222
<script src="../shared/playground-header.js"></script>

03-gesture-obs/app.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ document.addEventListener('DOMContentLoaded', async function() {
3030
let detectionLoopId = null;
3131
let isDetecting = false;
3232

33+
// VLM-aware client helper: routes through toggle when available
34+
function getVLMClient() {
35+
if (window.vlmToggle) return window.vlmToggle.getClient();
36+
return moondreamClient;
37+
}
38+
3339
let lastActionTime = 0;
3440
let thumbsUpDetections = 0;
3541
let thumbsDownDetections = 0;
@@ -52,7 +58,7 @@ document.addEventListener('DOMContentLoaded', async function() {
5258

5359
// Initialize VLM Toggle
5460
window.vlmToggle = new VLMToggle({
55-
containerSelector: '.control-panel h2',
61+
containerSelector: '.app-header h1',
5662
toolId: 'gesture-obs',
5763
onChange: (engine) => {
5864
window.reasoningConsole.logInfo('Switched to ' + engine + ' VLM');
@@ -223,12 +229,12 @@ document.addEventListener('DOMContentLoaded', async function() {
223229
}
224230

225231
async function detectGesture(gestureDescription) {
226-
if (!moondreamClient) return { detected: false, confidence: 0 };
232+
if (!getVLMClient()) return { detected: false, confidence: 0 };
227233

228234
const prompt = `Look at this image carefully. Is there a ${gestureDescription} gesture clearly visible? Answer with only YES or NO.`;
229235

230236
try {
231-
const result = await moondreamClient.askVideo(video, prompt);
237+
const result = await getVLMClient().askVideo(video, prompt);
232238
const answer = result.answer.toUpperCase().trim();
233239
const detected = answer.includes('YES');
234240

@@ -365,8 +371,8 @@ document.addEventListener('DOMContentLoaded', async function() {
365371
}
366372

367373
function startDetection() {
368-
if (!moondreamClient) {
369-
window.reasoningConsole.logError('Please configure Moondream API key first');
374+
if (!getVLMClient()) {
375+
window.reasoningConsole.logError('Please configure an API key first');
370376
window.apiKeyManager.showModal();
371377
return;
372378
}

03-gesture-obs/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,7 @@ <h3>📋 Activity Log</h3>
662662
<script src="obs-client.js"></script>
663663
<script src="../shared/openai-client.js"></script>
664664
<script src="../shared/vlm-toggle.js"></script>
665+
<script src="../shared/vlm-result-badge.js"></script>
665666
<script src="app.js"></script>
666667
<script src="../shared/ux-utils.js"></script>
667668
<script src="../shared/playground-header.js"></script>

04-scoreboard-extractor/app.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ document.addEventListener('DOMContentLoaded', async function() {
2222
let currentStream = null;
2323
let extractionLoopId = null;
2424
let isExtracting = false;
25+
26+
// VLM-aware client helper
27+
function getVLMClient() {
28+
if (window.vlmToggle) return window.vlmToggle.getClient();
29+
return client;
30+
}
2531

2632
let stats = {
2733
extractions: 0,
@@ -48,7 +54,7 @@ document.addEventListener('DOMContentLoaded', async function() {
4854

4955
// Initialize VLM Toggle
5056
window.vlmToggle = new VLMToggle({
51-
containerSelector: '.side-panel h3',
57+
containerSelector: '.app-header h1',
5258
toolId: 'scoreboard-extractor',
5359
onChange: (engine) => {
5460
window.reasoningConsole.logInfo('Switched to ' + engine + ' VLM');
@@ -164,7 +170,8 @@ document.addEventListener('DOMContentLoaded', async function() {
164170
}
165171

166172
async function extractScoreboard() {
167-
if (!client) {
173+
const activeClient = getVLMClient();
174+
if (!activeClient) {
168175
window.reasoningConsole.logError('No API key configured');
169176
window.apiKeyManager.showModal();
170177
return null;
@@ -186,8 +193,9 @@ Return ONLY valid JSON with no other text:
186193
window.reasoningConsole.logApiCall('/query', 0);
187194
updateStatus('Extracting...', true);
188195

189-
const result = await client.askVideo(video, prompt);
196+
const result = await activeClient.askVideo(video, prompt);
190197
const elapsed = Date.now() - startTime;
198+
VLMResultBadge.showCurrent(elapsed);
191199

192200
window.reasoningConsole.logInfo(`Response: ${result.answer}`);
193201

@@ -237,8 +245,8 @@ Return ONLY valid JSON with no other text:
237245
}
238246

239247
function startExtraction() {
240-
if (!client) {
241-
window.reasoningConsole.logError('Please configure Moondream API key first');
248+
if (!getVLMClient()) {
249+
window.reasoningConsole.logError('Please configure an API key first');
242250
window.apiKeyManager.showModal();
243251
return;
244252
}

04-scoreboard-extractor/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ <h3>⚙️ Settings</h3>
447447
<script src="../shared/video-source-adapter.js"></script>
448448
<script src="../shared/openai-client.js"></script>
449449
<script src="../shared/vlm-toggle.js"></script>
450+
<script src="../shared/vlm-result-badge.js"></script>
450451
<script src="app.js"></script>
451452
<script src="../shared/ux-utils.js"></script>
452453
<script src="../shared/playground-header.js"></script>

04b-scoreboard-ocr/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ <h3>⚙️ Controls</h3>
555555
<script src="../shared/video-source-adapter.js"></script>
556556
<script src="../shared/openai-client.js"></script>
557557
<script src="../shared/vlm-toggle.js"></script>
558+
<script src="../shared/vlm-result-badge.js"></script>
558559
<script src="app.js"></script>
559560
<script src="../shared/ux-utils.js"></script>
560561
<script src="../shared/playground-header.js"></script>

05-smart-counter/app.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ document.addEventListener('DOMContentLoaded', async function() {
2727
let client = null;
2828
let countingLoop = null;
2929
let isRunning = false;
30+
31+
// VLM-aware client helper
32+
function getVLMClient() {
33+
if (window.vlmToggle) return window.vlmToggle.getClient();
34+
return client;
35+
}
3036

3137
let currentCount = 0;
3238
let totalEntries = 0;
@@ -50,7 +56,7 @@ document.addEventListener('DOMContentLoaded', async function() {
5056

5157
// Initialize VLM Toggle
5258
window.vlmToggle = new VLMToggle({
53-
containerSelector: '.control-panel h2',
59+
containerSelector: '.app-header h1',
5460
toolId: 'smart-counter',
5561
onChange: (engine) => {
5662
window.reasoningConsole.logInfo('Switched to ' + engine + ' VLM');
@@ -190,8 +196,9 @@ document.addEventListener('DOMContentLoaded', async function() {
190196
const startTime = Date.now();
191197

192198
try {
193-
const result = await client.detectInVideo(video, targetInput.value);
199+
const result = await getVLMClient().detectInVideo(video, targetInput.value);
194200
const latency = Date.now() - startTime;
201+
VLMResultBadge.showCurrent(latency);
195202
const linePos = parseInt(linePositionSlider.value) / 100;
196203
const isLeftToRight = directionSelect.value === 'left-to-right';
197204

05-smart-counter/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ <h2>Settings</h2>
152152
<script src="../shared/video-source-adapter.js"></script>
153153
<script src="../shared/openai-client.js"></script>
154154
<script src="../shared/vlm-toggle.js"></script>
155+
<script src="../shared/vlm-result-badge.js"></script>
155156
<script src="app.js"></script>
156157
<script src="../shared/ux-utils.js"></script>
157158
<script src="../shared/playground-header.js"></script>

06-scene-analyzer/app.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ document.addEventListener('DOMContentLoaded', async function() {
2020
let totalResponseTime = 0;
2121
let currentStream = null;
2222

23+
// VLM-aware client helper
24+
function getVLMClient() {
25+
if (window.vlmToggle) return window.vlmToggle.getClient();
26+
return client;
27+
}
28+
2329
window.apiKeyManager = new APIKeyManager({
2430
requireMoondream: true,
2531
requireOpenAI: false,
@@ -34,7 +40,7 @@ document.addEventListener('DOMContentLoaded', async function() {
3440

3541
// Initialize VLM Toggle
3642
window.vlmToggle = new VLMToggle({
37-
containerSelector: '.control-panel h2',
43+
containerSelector: '.app-header h1',
3844
toolId: 'scene-analyzer',
3945
onChange: (engine) => {
4046
window.reasoningConsole.logInfo('Switched to ' + engine + ' VLM');
@@ -167,7 +173,7 @@ document.addEventListener('DOMContentLoaded', async function() {
167173
const startTime = Date.now();
168174

169175
try {
170-
const result = await client.ask(currentSnapshot, question);
176+
const result = await getVLMClient().ask(currentSnapshot, question);
171177
const elapsed = Date.now() - startTime;
172178

173179
window.reasoningConsole.logApiCall('/ask', elapsed);
@@ -179,6 +185,7 @@ document.addEventListener('DOMContentLoaded', async function() {
179185

180186
addMessage('assistant', result.answer);
181187
updateStatus(`Answered in ${elapsed}ms`);
188+
VLMResultBadge.showCurrent(elapsed);
182189
window.reasoningConsole.logDecision('Answer generated', `Response time: ${elapsed}ms`);
183190

184191
} catch (error) {

0 commit comments

Comments
 (0)