omnius 1.0.428 → 1.0.429
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +35 -3
- package/dist/scripts/live-whisper.py +7 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -603651,6 +603651,7 @@ var init_listen = __esm({
|
|
|
603651
603651
|
case "vad": {
|
|
603652
603652
|
lastHardwareVadAt = Date.now();
|
|
603653
603653
|
const doa = Number(evt.doa);
|
|
603654
|
+
this.emit("status", `Whisper VAD: ${evt.speech === true ? "speech" : "silence"}`);
|
|
603654
603655
|
updateListenLiveState({
|
|
603655
603656
|
speechActive: evt.speech === true,
|
|
603656
603657
|
doa: Number.isFinite(doa) ? doa : null
|
|
@@ -606474,6 +606475,7 @@ var init_live_sensors = __esm({
|
|
|
606474
606475
|
previewTickInFlight = false;
|
|
606475
606476
|
lastStreamFrameMtime = /* @__PURE__ */ new Map();
|
|
606476
606477
|
lastStreamPersistAt = 0;
|
|
606478
|
+
videoGeneration = 0;
|
|
606477
606479
|
videoInFlight = false;
|
|
606478
606480
|
audioInFlight = false;
|
|
606479
606481
|
audioActivityInFlight = false;
|
|
@@ -606676,7 +606678,12 @@ var init_live_sensors = __esm({
|
|
|
606676
606678
|
const next = (current + delta) % 360;
|
|
606677
606679
|
return this.setCameraRotation(device, next, "manual", `manual ${direction === "cw" ? "clockwise" : "counter-clockwise"} dashboard override`);
|
|
606678
606680
|
}
|
|
606681
|
+
isVideoWorkCurrent(generation) {
|
|
606682
|
+
return this.config.videoEnabled && generation === this.videoGeneration;
|
|
606683
|
+
}
|
|
606679
606684
|
async autoOrientCamera(device = this.config.selectedCamera, options2 = {}) {
|
|
606685
|
+
const generation = this.videoGeneration;
|
|
606686
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
606680
606687
|
const target = device || this.config.selectedCamera || firstDeviceId(this.devices.video);
|
|
606681
606688
|
if (!target) return "No camera selected. Use /live camera <device> or select a camera in /live.";
|
|
606682
606689
|
if (options2.onlyIfUnset && this.getCameraOrientation(target)) {
|
|
@@ -606693,17 +606700,20 @@ var init_live_sensors = __esm({
|
|
|
606693
606700
|
framePath = streamFrame.path;
|
|
606694
606701
|
}
|
|
606695
606702
|
if (!framePath) {
|
|
606703
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
606696
606704
|
const captured = await new CameraCaptureTool().execute({
|
|
606697
606705
|
action: "capture",
|
|
606698
606706
|
device: target,
|
|
606699
606707
|
rotate_degrees: 0
|
|
606700
606708
|
});
|
|
606709
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
606701
606710
|
if (!captured.success) {
|
|
606702
606711
|
return `Camera orientation detection could not capture ${target}: ${captured.error || captured.output || "unknown error"}`;
|
|
606703
606712
|
}
|
|
606704
606713
|
framePath = extractSavedImagePath(captured.output, this.repoRoot);
|
|
606705
606714
|
}
|
|
606706
606715
|
if (!framePath) return `Camera orientation detection captured ${target}, but no frame path was returned.`;
|
|
606716
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
606707
606717
|
const cvScores = await scoreCameraOrientationWithOpenCv(framePath);
|
|
606708
606718
|
const cvDecision = cvScores ? chooseCameraOrientationFromScores(cvScores) : null;
|
|
606709
606719
|
const prompt = [
|
|
@@ -606721,6 +606731,7 @@ var init_live_sensors = __esm({
|
|
|
606721
606731
|
prompt,
|
|
606722
606732
|
model: "moondream3-preview"
|
|
606723
606733
|
});
|
|
606734
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
606724
606735
|
if (!vision.success) {
|
|
606725
606736
|
if (cvDecision) {
|
|
606726
606737
|
const orientation2 = this.setCameraRotation(target, cvDecision.rotation, "auto", cvDecision.reason, cvDecision.confidence);
|
|
@@ -606774,12 +606785,18 @@ var init_live_sensors = __esm({
|
|
|
606774
606785
|
return this.devices;
|
|
606775
606786
|
}
|
|
606776
606787
|
configure(patch) {
|
|
606788
|
+
const wasVideoEnabled = this.config.videoEnabled;
|
|
606777
606789
|
this.config = {
|
|
606778
606790
|
...this.config,
|
|
606779
606791
|
...patch,
|
|
606780
606792
|
videoIntervalMs: Math.max(MIN_VIDEO_INTERVAL_MS, Number(patch.videoIntervalMs ?? this.config.videoIntervalMs)),
|
|
606781
606793
|
audioIntervalMs: Math.max(MIN_AUDIO_INTERVAL_MS, Number(patch.audioIntervalMs ?? this.config.audioIntervalMs))
|
|
606782
606794
|
};
|
|
606795
|
+
if (wasVideoEnabled && !this.config.videoEnabled) {
|
|
606796
|
+
this.videoGeneration++;
|
|
606797
|
+
this.lastStreamFrameMtime.clear();
|
|
606798
|
+
this.cameraStreamers?.stopAll();
|
|
606799
|
+
}
|
|
606783
606800
|
this.persist();
|
|
606784
606801
|
this.clearLoopTimers();
|
|
606785
606802
|
this.ensureLoops();
|
|
@@ -606858,6 +606875,8 @@ var init_live_sensors = __esm({
|
|
|
606858
606875
|
return options2.agent ? "Live PFC run enabled: visual/audio feedback is active and significant events can launch background agent review." : "Live run enabled: visual/audio feedback is active and live context will update each turn.";
|
|
606859
606876
|
}
|
|
606860
606877
|
async previewCamera(device = this.config.selectedCamera, options2 = {}) {
|
|
606878
|
+
const generation = options2.generation ?? this.videoGeneration;
|
|
606879
|
+
if (!this.isVideoWorkCurrent(generation)) return { ok: false, message: "Video context is disabled." };
|
|
606861
606880
|
const source = device || firstDeviceId(this.devices.video);
|
|
606862
606881
|
if (!source) return { ok: false, message: "No camera selected. Use /live to select a camera after device discovery." };
|
|
606863
606882
|
const orientation = this.getCameraOrientation(source);
|
|
@@ -606867,6 +606886,7 @@ var init_live_sensors = __esm({
|
|
|
606867
606886
|
const displayPath2 = relative11(this.repoRoot, streamFrame.path).startsWith("..") ? streamFrame.path : relative11(this.repoRoot, streamFrame.path);
|
|
606868
606887
|
const previewWidth2 = Math.max(42, Math.min(120, Math.floor(Number(options2.previewWidth ?? (process.stdout.columns || 100) - 14))));
|
|
606869
606888
|
const preview2 = await buildImageAsciiPreview(streamFrame.path, { width: previewWidth2 });
|
|
606889
|
+
if (!this.isVideoWorkCurrent(generation)) return { ok: false, message: "Video context is disabled." };
|
|
606870
606890
|
if (preview2?.ascii || preview2?.plainAscii) {
|
|
606871
606891
|
const observedAt2 = Date.now();
|
|
606872
606892
|
const cameraView2 = {
|
|
@@ -606909,6 +606929,7 @@ var init_live_sensors = __esm({
|
|
|
606909
606929
|
device: source,
|
|
606910
606930
|
rotate_degrees: rotation
|
|
606911
606931
|
});
|
|
606932
|
+
if (!this.isVideoWorkCurrent(generation)) return { ok: false, message: "Video context is disabled." };
|
|
606912
606933
|
if (!result.success) {
|
|
606913
606934
|
const error = result.error || result.output || "camera capture failed";
|
|
606914
606935
|
const observedAt2 = Date.now();
|
|
@@ -606953,6 +606974,7 @@ var init_live_sensors = __esm({
|
|
|
606953
606974
|
const displayPath = relative11(this.repoRoot, framePath).startsWith("..") ? framePath : relative11(this.repoRoot, framePath);
|
|
606954
606975
|
const previewWidth = Math.max(42, Math.min(120, Math.floor(Number(options2.previewWidth ?? (process.stdout.columns || 100) - 14))));
|
|
606955
606976
|
const preview = await buildImageAsciiPreview(framePath, { width: previewWidth });
|
|
606977
|
+
if (!this.isVideoWorkCurrent(generation)) return { ok: false, message: "Video context is disabled." };
|
|
606956
606978
|
const asciiContext = preview ? formatImageAsciiContext(preview, displayPath) : void 0;
|
|
606957
606979
|
const observedAt = Date.now();
|
|
606958
606980
|
const cameraView = {
|
|
@@ -607061,7 +607083,10 @@ var init_live_sensors = __esm({
|
|
|
607061
607083
|
}
|
|
607062
607084
|
}
|
|
607063
607085
|
async sampleSingleVideoNow(source, forceInfer, previewWidth, options2 = {}) {
|
|
607064
|
-
const
|
|
607086
|
+
const generation = options2.generation ?? this.videoGeneration;
|
|
607087
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
607088
|
+
const preview = await this.previewCamera(source, { emit: false, previewWidth, generation });
|
|
607089
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
607065
607090
|
void this.runLiveVlm(source, preview.ok ? preview.framePath : void 0).catch(() => {
|
|
607066
607091
|
});
|
|
607067
607092
|
let inference = "";
|
|
@@ -607096,6 +607121,7 @@ var init_live_sensors = __esm({
|
|
|
607096
607121
|
crop_faces: true,
|
|
607097
607122
|
recognize_faces: true
|
|
607098
607123
|
});
|
|
607124
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
607099
607125
|
inference = result.success ? String(result.output || result.llmContent || "") : `Video inference failed: ${result.error || result.output || "unknown error"}`;
|
|
607100
607126
|
const livePayload = result.success ? parseLiveMediaPayload(result.llmContent || result.output) : null;
|
|
607101
607127
|
if (livePayload) livePayload.source = source;
|
|
@@ -607168,6 +607194,7 @@ var init_live_sensors = __esm({
|
|
|
607168
607194
|
if (this.config.clipEnabled && preview.ok && preview.framePath && source && sampledAt - lastClip >= 5e3) {
|
|
607169
607195
|
this.lastClipAt.set(source, sampledAt);
|
|
607170
607196
|
clipSummary = await this.recognizeFrameObjects(preview.framePath, source, sampledAt, { emit: false });
|
|
607197
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
607171
607198
|
const current = this.snapshot.cameras?.[source];
|
|
607172
607199
|
if (current) {
|
|
607173
607200
|
const clipLine = formatClipDashboardSummary(clipSummary);
|
|
@@ -607196,9 +607223,12 @@ ${clipSummary}` : ""].filter(Boolean).join("\n");
|
|
|
607196
607223
|
return result;
|
|
607197
607224
|
}
|
|
607198
607225
|
async sampleVideoNow(forceInfer = this.config.inferEnabled, options2 = {}) {
|
|
607226
|
+
const generation = options2.generation ?? this.videoGeneration;
|
|
607227
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
607199
607228
|
if (this.videoInFlight) return "Video sampler is already running.";
|
|
607200
607229
|
this.videoInFlight = true;
|
|
607201
607230
|
try {
|
|
607231
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
607202
607232
|
const allSources = this.activeVideoSources();
|
|
607203
607233
|
if (allSources.length === 0) return "No camera selected. Use /live refresh after connecting hardware.";
|
|
607204
607234
|
const sources = options2.mode === "round-robin" ? [allSources[this.nextVideoSourceIndex++ % allSources.length]] : allSources;
|
|
@@ -607206,8 +607236,10 @@ ${clipSummary}` : ""].filter(Boolean).join("\n");
|
|
|
607206
607236
|
const outputs = [];
|
|
607207
607237
|
const previewWidth = liveDashboardPreviewWidthForSources(allSources.length);
|
|
607208
607238
|
for (const source of sources) {
|
|
607209
|
-
|
|
607239
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
607240
|
+
outputs.push(await this.sampleSingleVideoNow(source, forceInfer, previewWidth, { ...options2, generation }));
|
|
607210
607241
|
}
|
|
607242
|
+
if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
|
|
607211
607243
|
this.emitDashboard();
|
|
607212
607244
|
return outputs.map((output, index) => `## Camera ${sources[index]}
|
|
607213
607245
|
${output}`).join("\n\n");
|
|
@@ -737161,7 +737193,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
737161
737193
|
statusBar.setMicActivity(evt.speechActive, evt.levelDb);
|
|
737162
737194
|
});
|
|
737163
737195
|
listenEng.on("info", (msg) => {
|
|
737164
|
-
if (/consensus rejected|loading whisper|whisper model loaded/i.test(msg)) {
|
|
737196
|
+
if (/consensus rejected|loading whisper|whisper model loaded|Whisper VAD|no accepted speech text|very short utterance/i.test(msg)) {
|
|
737165
737197
|
writeContent(() => renderInfo(`[voicechat/asr] ${msg}`));
|
|
737166
737198
|
}
|
|
737167
737199
|
});
|
|
@@ -443,13 +443,18 @@ def main():
|
|
|
443
443
|
result = run_transcribe(model, amplify(samples))
|
|
444
444
|
text = _segment_filtered_text(result)
|
|
445
445
|
if text:
|
|
446
|
-
emit_transcript(
|
|
446
|
+
emit_transcript(
|
|
447
|
+
text,
|
|
448
|
+
is_final=False,
|
|
449
|
+
consensus=False if consensus_model is not None else None,
|
|
450
|
+
)
|
|
447
451
|
except Exception as e:
|
|
448
452
|
emit_error(f"Transcription error: {e}")
|
|
449
453
|
|
|
450
454
|
def transcribe_final(samples):
|
|
451
455
|
nonlocal last_final_text
|
|
452
456
|
if len(samples) < int(0.4 * SAMPLE_RATE):
|
|
457
|
+
emit_status("Whisper ignored very short utterance.")
|
|
453
458
|
return
|
|
454
459
|
samples = amplify(samples)
|
|
455
460
|
try:
|
|
@@ -466,6 +471,7 @@ def main():
|
|
|
466
471
|
|
|
467
472
|
text = _segment_filtered_text(result)
|
|
468
473
|
if not text:
|
|
474
|
+
emit_status("Whisper final produced no accepted speech text.")
|
|
469
475
|
return
|
|
470
476
|
if secondary is not None:
|
|
471
477
|
secondary_text = _segment_filtered_text(secondary)
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.429",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.429",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED