open-agents-ai 0.187.547 → 0.187.549
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 +234 -24
- package/dist/scripts/transcribe-file.py +63 -0
- package/npm-shrinkwrap.json +12 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -539822,6 +539822,91 @@ function findMicCaptureCommand() {
|
|
|
539822
539822
|
}
|
|
539823
539823
|
return null;
|
|
539824
539824
|
}
|
|
539825
|
+
function findTranscribeFileScript() {
|
|
539826
|
+
const thisDir = dirname24(fileURLToPath10(import.meta.url));
|
|
539827
|
+
const candidates = [
|
|
539828
|
+
join87(thisDir, "../../../../packages/execution/scripts/transcribe-file.py"),
|
|
539829
|
+
join87(thisDir, "../../../packages/execution/scripts/transcribe-file.py"),
|
|
539830
|
+
join87(thisDir, "../../execution/scripts/transcribe-file.py"),
|
|
539831
|
+
join87(thisDir, "../scripts/transcribe-file.py"),
|
|
539832
|
+
join87(thisDir, "../../scripts/transcribe-file.py")
|
|
539833
|
+
];
|
|
539834
|
+
for (const p2 of candidates) {
|
|
539835
|
+
if (existsSync71(p2)) return p2;
|
|
539836
|
+
}
|
|
539837
|
+
try {
|
|
539838
|
+
const globalRoot = execSync46("npm root -g", {
|
|
539839
|
+
encoding: "utf-8",
|
|
539840
|
+
timeout: 5e3,
|
|
539841
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
539842
|
+
}).trim();
|
|
539843
|
+
const candidates2 = [
|
|
539844
|
+
join87(globalRoot, "open-agents-ai", "dist", "scripts", "transcribe-file.py"),
|
|
539845
|
+
join87(globalRoot, "open-agents-ai", "scripts", "transcribe-file.py")
|
|
539846
|
+
];
|
|
539847
|
+
for (const p2 of candidates2) {
|
|
539848
|
+
if (existsSync71(p2)) return p2;
|
|
539849
|
+
}
|
|
539850
|
+
} catch {
|
|
539851
|
+
}
|
|
539852
|
+
return null;
|
|
539853
|
+
}
|
|
539854
|
+
async function transcribeFileViaWhisper(filePath, model) {
|
|
539855
|
+
const script = findTranscribeFileScript();
|
|
539856
|
+
if (!script) return null;
|
|
539857
|
+
const bin = process.platform === "win32" ? "Scripts" : "bin";
|
|
539858
|
+
const exe = process.platform === "win32" ? "python.exe" : "python3";
|
|
539859
|
+
const venvPython2 = join87(homedir25(), ".open-agents", "venv", bin, exe);
|
|
539860
|
+
if (!existsSync71(venvPython2)) return null;
|
|
539861
|
+
return new Promise((resolve43) => {
|
|
539862
|
+
const child = spawn18(venvPython2, [script], {
|
|
539863
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
539864
|
+
env: process.env
|
|
539865
|
+
});
|
|
539866
|
+
let out = "";
|
|
539867
|
+
let err = "";
|
|
539868
|
+
let timer = null;
|
|
539869
|
+
const stop2 = (val) => {
|
|
539870
|
+
if (timer) clearTimeout(timer);
|
|
539871
|
+
try {
|
|
539872
|
+
child.kill("SIGTERM");
|
|
539873
|
+
} catch {
|
|
539874
|
+
}
|
|
539875
|
+
resolve43(val ? parse3(val) : null);
|
|
539876
|
+
};
|
|
539877
|
+
function parse3(raw) {
|
|
539878
|
+
try {
|
|
539879
|
+
const j = JSON.parse(raw);
|
|
539880
|
+
if (j.error) return null;
|
|
539881
|
+
if (typeof j.text !== "string") return null;
|
|
539882
|
+
return { text: j.text.trim(), duration: null, speakers: [], segments: [] };
|
|
539883
|
+
} catch {
|
|
539884
|
+
return null;
|
|
539885
|
+
}
|
|
539886
|
+
}
|
|
539887
|
+
child.stdout?.on("data", (d2) => {
|
|
539888
|
+
out += d2.toString("utf-8");
|
|
539889
|
+
});
|
|
539890
|
+
child.stderr?.on("data", (d2) => {
|
|
539891
|
+
err += d2.toString("utf-8");
|
|
539892
|
+
});
|
|
539893
|
+
child.once("error", () => stop2(null));
|
|
539894
|
+
child.once("close", () => {
|
|
539895
|
+
if (out.trim()) resolve43(parse3(out));
|
|
539896
|
+
else {
|
|
539897
|
+
void err;
|
|
539898
|
+
resolve43(null);
|
|
539899
|
+
}
|
|
539900
|
+
});
|
|
539901
|
+
timer = setTimeout(() => stop2(null), 12e4);
|
|
539902
|
+
try {
|
|
539903
|
+
child.stdin?.write(JSON.stringify({ path: filePath, model }) + "\n");
|
|
539904
|
+
child.stdin?.end();
|
|
539905
|
+
} catch {
|
|
539906
|
+
stop2(null);
|
|
539907
|
+
}
|
|
539908
|
+
});
|
|
539909
|
+
}
|
|
539825
539910
|
function findLiveWhisperScript() {
|
|
539826
539911
|
const thisDir = dirname24(fileURLToPath10(import.meta.url));
|
|
539827
539912
|
const candidates = [
|
|
@@ -540523,32 +540608,48 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
540523
540608
|
} catch {
|
|
540524
540609
|
}
|
|
540525
540610
|
}
|
|
540526
|
-
if (!tc) return null;
|
|
540527
540611
|
ensureVenvForTranscribeCli();
|
|
540528
|
-
|
|
540529
|
-
|
|
540530
|
-
|
|
540531
|
-
|
|
540532
|
-
|
|
540533
|
-
|
|
540534
|
-
|
|
540612
|
+
let lastErr = null;
|
|
540613
|
+
if (tc) {
|
|
540614
|
+
try {
|
|
540615
|
+
const result = await tc.transcribe(filePath, {
|
|
540616
|
+
model: this.config.model,
|
|
540617
|
+
format: "json",
|
|
540618
|
+
diarize: false,
|
|
540619
|
+
wordTimestamps: false
|
|
540620
|
+
});
|
|
540621
|
+
if (outputDir) {
|
|
540622
|
+
const { basename: basename21 } = await import("node:path");
|
|
540623
|
+
const transcriptDir = join87(outputDir, ".oa", "transcripts");
|
|
540624
|
+
mkdirSync38(transcriptDir, { recursive: true });
|
|
540625
|
+
const outFile = join87(transcriptDir, `${basename21(filePath)}.txt`);
|
|
540626
|
+
writeFileSync34(outFile, result.text, "utf-8");
|
|
540627
|
+
}
|
|
540628
|
+
return {
|
|
540629
|
+
text: result.text,
|
|
540630
|
+
duration: result.duration,
|
|
540631
|
+
speakers: result.speakers,
|
|
540632
|
+
segments: result.segments
|
|
540633
|
+
};
|
|
540634
|
+
} catch (err) {
|
|
540635
|
+
lastErr = err;
|
|
540636
|
+
}
|
|
540637
|
+
}
|
|
540638
|
+
const fb = await transcribeFileViaWhisper(filePath, this.config.model);
|
|
540639
|
+
if (fb) {
|
|
540535
540640
|
if (outputDir) {
|
|
540536
540641
|
const { basename: basename21 } = await import("node:path");
|
|
540537
540642
|
const transcriptDir = join87(outputDir, ".oa", "transcripts");
|
|
540538
540643
|
mkdirSync38(transcriptDir, { recursive: true });
|
|
540539
540644
|
const outFile = join87(transcriptDir, `${basename21(filePath)}.txt`);
|
|
540540
|
-
writeFileSync34(outFile,
|
|
540645
|
+
writeFileSync34(outFile, fb.text, "utf-8");
|
|
540541
540646
|
}
|
|
540542
|
-
return
|
|
540543
|
-
|
|
540544
|
-
|
|
540545
|
-
|
|
540546
|
-
segments: result.segments
|
|
540547
|
-
};
|
|
540548
|
-
} catch (err) {
|
|
540549
|
-
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
540550
|
-
return null;
|
|
540647
|
+
return fb;
|
|
540648
|
+
}
|
|
540649
|
+
if (lastErr) {
|
|
540650
|
+
this.emit("error", lastErr instanceof Error ? lastErr : new Error(String(lastErr)));
|
|
540551
540651
|
}
|
|
540652
|
+
return null;
|
|
540552
540653
|
}
|
|
540553
540654
|
// -------------------------------------------------------------------------
|
|
540554
540655
|
// Auto-mode silence detection
|
|
@@ -587603,7 +587704,20 @@ async function handleGenerateShare(ctx3) {
|
|
|
587603
587704
|
return true;
|
|
587604
587705
|
}
|
|
587605
587706
|
const directOnly = body["direct"] === true;
|
|
587606
|
-
|
|
587707
|
+
let peerInfo = directOnly ? null : resolveLocalPeerId();
|
|
587708
|
+
if (!directOnly && !peerInfo) {
|
|
587709
|
+
try {
|
|
587710
|
+
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
|
|
587711
|
+
const repoRoot = process.env["OA_NEXUS_DIR"] ? String(process.env["OA_NEXUS_DIR"]).replace(/[\\/]\.oa[\\/]nexus$/, "") : process.cwd();
|
|
587712
|
+
const tool = new NexusTool2(repoRoot);
|
|
587713
|
+
await Promise.race([
|
|
587714
|
+
tool.execute({ action: "connect" }),
|
|
587715
|
+
new Promise((_r, rej) => setTimeout(() => rej(new Error("nexus connect 25s budget")), 25e3))
|
|
587716
|
+
]).catch(() => null);
|
|
587717
|
+
peerInfo = resolveLocalPeerId();
|
|
587718
|
+
} catch {
|
|
587719
|
+
}
|
|
587720
|
+
}
|
|
587607
587721
|
const scheme = String(req2.headers["x-forwarded-proto"] || (req2.socket?.encrypted ? "https" : "http"));
|
|
587608
587722
|
const { getLocalOnion: getLocalOnion2 } = await Promise.resolve().then(() => (init_tor_fallback(), tor_fallback_exports));
|
|
587609
587723
|
const onion = getLocalOnion2();
|
|
@@ -592326,11 +592440,13 @@ function installRemoteFetchProxy() {
|
|
|
592326
592440
|
});
|
|
592327
592441
|
if (wantsStream) {
|
|
592328
592442
|
// Pass through as-is — receiver returns text/event-stream.
|
|
592329
|
-
|
|
592443
|
+
const sResp = await _origFetch('/v1/remote-proxy', {
|
|
592330
592444
|
method: 'POST',
|
|
592331
592445
|
headers: { 'content-type': 'application/json', 'accept': 'text/event-stream' },
|
|
592332
592446
|
body: proxyBody,
|
|
592333
592447
|
});
|
|
592448
|
+
_handleRemoteProxyFailure(sResp);
|
|
592449
|
+
return sResp;
|
|
592334
592450
|
}
|
|
592335
592451
|
// Non-stream: receiver returns a JSON envelope { status, headers, body }.
|
|
592336
592452
|
// Synthesize a Response that mimics the original remote response.
|
|
@@ -592339,7 +592455,10 @@ function installRemoteFetchProxy() {
|
|
|
592339
592455
|
headers: { 'content-type': 'application/json' },
|
|
592340
592456
|
body: proxyBody,
|
|
592341
592457
|
});
|
|
592342
|
-
if (!proxyResp.ok)
|
|
592458
|
+
if (!proxyResp.ok) {
|
|
592459
|
+
_handleRemoteProxyFailure(proxyResp.clone());
|
|
592460
|
+
return proxyResp;
|
|
592461
|
+
}
|
|
592343
592462
|
let env = null;
|
|
592344
592463
|
try { env = await proxyResp.json(); } catch {}
|
|
592345
592464
|
if (!env || typeof env !== 'object') {
|
|
@@ -592366,6 +592485,43 @@ function installRemoteFetchProxy() {
|
|
|
592366
592485
|
return new Response(bodyText, { status, headers: headersOut });
|
|
592367
592486
|
};
|
|
592368
592487
|
}
|
|
592488
|
+
// ─── Remote-proxy failure recovery ──────────────────────────────────────
|
|
592489
|
+
// When /v1/remote-proxy returns 502/503 repeatedly, the remote peer is
|
|
592490
|
+
// unreachable (nexus dead, key revoked, target offline). Clear the
|
|
592491
|
+
// activeRemoteShare flag so the GUI exits the trapped state where every
|
|
592492
|
+
// fetch loops through a broken proxy. Surface a one-line banner so the
|
|
592493
|
+
// user knows what happened.
|
|
592494
|
+
let _remoteProxy502Count = 0;
|
|
592495
|
+
async function _handleRemoteProxyFailure(resp) {
|
|
592496
|
+
if (!resp || (resp.status !== 502 && resp.status !== 503)) {
|
|
592497
|
+
_remoteProxy502Count = 0;
|
|
592498
|
+
return;
|
|
592499
|
+
}
|
|
592500
|
+
_remoteProxy502Count++;
|
|
592501
|
+
// After 3 consecutive transport failures, give up and clear state.
|
|
592502
|
+
if (_remoteProxy502Count >= 3) {
|
|
592503
|
+
let detail = '';
|
|
592504
|
+
try { const j = await resp.json(); detail = j && (j.detail || j.message) ? String(j.detail || j.message) : ''; } catch {}
|
|
592505
|
+
try { localStorage.removeItem('oa.activeRemoteShare'); } catch {}
|
|
592506
|
+
_showRemoteRecoveryBanner(detail);
|
|
592507
|
+
_remoteProxy502Count = 0;
|
|
592508
|
+
// Reload after a beat so the freshly-cleared state propagates and
|
|
592509
|
+
// the original (non-proxied) fetch can succeed.
|
|
592510
|
+
setTimeout(() => { try { location.reload(); } catch {} }, 2500);
|
|
592511
|
+
}
|
|
592512
|
+
}
|
|
592513
|
+
function _showRemoteRecoveryBanner(detail) {
|
|
592514
|
+
if (document.getElementById('remote-recovery-banner')) return;
|
|
592515
|
+
const div = document.createElement('div');
|
|
592516
|
+
div.id = 'remote-recovery-banner';
|
|
592517
|
+
div.style.cssText = 'position:fixed;top:0;left:0;right:0;z-index:9999;background:var(--color-error);color:#fff;padding:8px 14px;font-size:0.78rem;font-family:inherit;display:flex;align-items:center;gap:10px';
|
|
592518
|
+
div.innerHTML =
|
|
592519
|
+
'<span>⚠ Remote share unreachable — disconnected. ' + (detail ? '(' + (String(detail).slice(0, 120).replace(/[<>&]/g, '')) + ') ' : '') + '</span>' +
|
|
592520
|
+
'<span style="flex:1"></span>' +
|
|
592521
|
+
'<button onclick="document.getElementById(\\'remote-recovery-banner\\').remove()" style="background:#fff2;color:#fff;border:1px solid #fff5;padding:2px 8px;border-radius:3px;cursor:pointer;font-size:0.74rem">dismiss</button>';
|
|
592522
|
+
document.body.appendChild(div);
|
|
592523
|
+
}
|
|
592524
|
+
|
|
592369
592525
|
// Auto-install on every load if a remote share is active.
|
|
592370
592526
|
try {
|
|
592371
592527
|
if (getActiveRemoteShare()) installRemoteFetchProxy();
|
|
@@ -598677,6 +598833,26 @@ function formatMetrics() {
|
|
|
598677
598833
|
lines.push(`oa_errors_total ${metrics.totalErrors}`);
|
|
598678
598834
|
return lines.join("\n") + "\n";
|
|
598679
598835
|
}
|
|
598836
|
+
function pcmToWav(pcm, sampleRate, channels, bitsPerSample) {
|
|
598837
|
+
const byteRate = sampleRate * channels * (bitsPerSample / 8);
|
|
598838
|
+
const blockAlign = channels * (bitsPerSample / 8);
|
|
598839
|
+
const dataSize = pcm.length;
|
|
598840
|
+
const header = Buffer.alloc(44);
|
|
598841
|
+
header.write("RIFF", 0);
|
|
598842
|
+
header.writeUInt32LE(36 + dataSize, 4);
|
|
598843
|
+
header.write("WAVE", 8);
|
|
598844
|
+
header.write("fmt ", 12);
|
|
598845
|
+
header.writeUInt32LE(16, 16);
|
|
598846
|
+
header.writeUInt16LE(1, 20);
|
|
598847
|
+
header.writeUInt16LE(channels, 22);
|
|
598848
|
+
header.writeUInt32LE(sampleRate, 24);
|
|
598849
|
+
header.writeUInt32LE(byteRate, 28);
|
|
598850
|
+
header.writeUInt16LE(blockAlign, 32);
|
|
598851
|
+
header.writeUInt16LE(bitsPerSample, 34);
|
|
598852
|
+
header.write("data", 36);
|
|
598853
|
+
header.writeUInt32LE(dataSize, 40);
|
|
598854
|
+
return Buffer.concat([header, pcm]);
|
|
598855
|
+
}
|
|
598680
598856
|
function jsonResponse(res, status, body) {
|
|
598681
598857
|
const payload = JSON.stringify(body);
|
|
598682
598858
|
res.writeHead(status, { "Content-Type": "application/json" });
|
|
@@ -602566,9 +602742,11 @@ data: ${JSON.stringify(data)}
|
|
|
602566
602742
|
} catch {
|
|
602567
602743
|
}
|
|
602568
602744
|
};
|
|
602745
|
+
let receivedAnyTranscript = false;
|
|
602569
602746
|
const onTranscript = (payload) => {
|
|
602570
602747
|
const p2 = payload;
|
|
602571
602748
|
if (!p2 || typeof p2.text !== "string") return;
|
|
602749
|
+
receivedAnyTranscript = true;
|
|
602572
602750
|
sse(p2.final ? "final" : "partial", { text: p2.text });
|
|
602573
602751
|
};
|
|
602574
602752
|
listen.on("transcript", onTranscript);
|
|
@@ -602584,19 +602762,51 @@ data: ${JSON.stringify(data)}
|
|
|
602584
602762
|
cleanup();
|
|
602585
602763
|
res.end();
|
|
602586
602764
|
});
|
|
602765
|
+
const pcmChunks = [];
|
|
602587
602766
|
req2.on("data", (chunk) => {
|
|
602767
|
+
pcmChunks.push(chunk);
|
|
602588
602768
|
try {
|
|
602589
602769
|
const t2 = listen.liveTranscriber;
|
|
602590
602770
|
if (t2?.write) t2.write(chunk);
|
|
602591
602771
|
} catch {
|
|
602592
602772
|
}
|
|
602593
602773
|
});
|
|
602594
|
-
req2.on("end", () => {
|
|
602595
|
-
|
|
602774
|
+
req2.on("end", async () => {
|
|
602775
|
+
await new Promise((r2) => setTimeout(r2, 1500));
|
|
602776
|
+
if (receivedAnyTranscript) {
|
|
602596
602777
|
sse("done", { ok: true });
|
|
602597
602778
|
cleanup();
|
|
602598
602779
|
res.end();
|
|
602599
|
-
|
|
602780
|
+
return;
|
|
602781
|
+
}
|
|
602782
|
+
try {
|
|
602783
|
+
const pcm = Buffer.concat(pcmChunks);
|
|
602784
|
+
if (pcm.length < 320) {
|
|
602785
|
+
sse("done", { ok: true, empty: true });
|
|
602786
|
+
cleanup();
|
|
602787
|
+
res.end();
|
|
602788
|
+
return;
|
|
602789
|
+
}
|
|
602790
|
+
const wav = pcmToWav(pcm, 16e3, 1, 16);
|
|
602791
|
+
const fs7 = await import("node:fs");
|
|
602792
|
+
const os8 = await import("node:os");
|
|
602793
|
+
const path8 = await import("node:path");
|
|
602794
|
+
const tmpPath = path8.join(os8.tmpdir(), `oa-stream-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.wav`);
|
|
602795
|
+
fs7.writeFileSync(tmpPath, wav);
|
|
602796
|
+
const result = await listen.transcribeFile(tmpPath).catch(() => null);
|
|
602797
|
+
try {
|
|
602798
|
+
fs7.unlinkSync(tmpPath);
|
|
602799
|
+
} catch {
|
|
602800
|
+
}
|
|
602801
|
+
if (result && result.text) {
|
|
602802
|
+
sse("final", { text: result.text });
|
|
602803
|
+
}
|
|
602804
|
+
sse("done", { ok: true, mode: "one-shot" });
|
|
602805
|
+
} catch (err) {
|
|
602806
|
+
sse("error", { message: err instanceof Error ? err.message : String(err) });
|
|
602807
|
+
}
|
|
602808
|
+
cleanup();
|
|
602809
|
+
res.end();
|
|
602600
602810
|
});
|
|
602601
602811
|
} catch (err) {
|
|
602602
602812
|
jsonResponse(res, 500, { error: "transcribe_stream_failed", message: err instanceof Error ? err.message : String(err) });
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Transcribe an audio file using openai-whisper (CPU-only).
|
|
4
|
+
|
|
5
|
+
stdin: JSON {"path": "...", "model": "tiny|base|small|medium|large-v3"}
|
|
6
|
+
stdout: JSON {"text": "...", "duration": null, "segments": []}
|
|
7
|
+
or {"error": "<kind>", "message": "..."}
|
|
8
|
+
|
|
9
|
+
Force-loads on CPU because the venv's torch may not match the local GPU
|
|
10
|
+
(e.g. a GT 1030 with sm_61 against a sm_75+ torch build) — those mismatches
|
|
11
|
+
print noisy CUDA warnings and then crash. CPU is slower but always works.
|
|
12
|
+
"""
|
|
13
|
+
import sys, os, json, warnings
|
|
14
|
+
|
|
15
|
+
# Quiet CUDA warnings from torch even though we won't use the GPU.
|
|
16
|
+
warnings.filterwarnings("ignore")
|
|
17
|
+
os.environ.setdefault("CUDA_VISIBLE_DEVICES", "") # hide all GPUs
|
|
18
|
+
os.environ.setdefault("PYTHONWARNINGS", "ignore")
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
import whisper
|
|
22
|
+
except Exception as e:
|
|
23
|
+
print(json.dumps({"error": "deps_missing", "message": str(e)}))
|
|
24
|
+
sys.exit(0)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def main() -> None:
|
|
28
|
+
raw = sys.stdin.read()
|
|
29
|
+
try:
|
|
30
|
+
data = json.loads(raw) if raw.strip() else {}
|
|
31
|
+
except Exception as e:
|
|
32
|
+
print(json.dumps({"error": "bad_input", "message": str(e)}))
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
path = data.get("path")
|
|
36
|
+
if not path or not os.path.exists(path):
|
|
37
|
+
print(json.dumps({"error": "file_not_found", "path": path or ""}))
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
model_name = data.get("model") or "tiny"
|
|
41
|
+
try:
|
|
42
|
+
model = whisper.load_model(model_name, device="cpu")
|
|
43
|
+
result = model.transcribe(path, fp16=False)
|
|
44
|
+
except Exception as e:
|
|
45
|
+
print(json.dumps({"error": "whisper_failed", "message": str(e)}))
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
text = (result.get("text") or "").strip()
|
|
49
|
+
raw_segments = result.get("segments") or []
|
|
50
|
+
segments = [
|
|
51
|
+
{
|
|
52
|
+
"start": float(s.get("start", 0.0)),
|
|
53
|
+
"end": float(s.get("end", 0.0)),
|
|
54
|
+
"text": (s.get("text") or "").strip(),
|
|
55
|
+
}
|
|
56
|
+
for s in raw_segments
|
|
57
|
+
]
|
|
58
|
+
duration = float(segments[-1]["end"]) if segments else None
|
|
59
|
+
print(json.dumps({"text": text, "duration": duration, "segments": segments}))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
main()
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-agents-ai",
|
|
3
|
-
"version": "0.187.
|
|
3
|
+
"version": "0.187.549",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "open-agents-ai",
|
|
9
|
-
"version": "0.187.
|
|
9
|
+
"version": "0.187.549",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "CC-BY-NC-4.0",
|
|
12
12
|
"dependencies": {
|
|
@@ -3132,12 +3132,12 @@
|
|
|
3132
3132
|
}
|
|
3133
3133
|
},
|
|
3134
3134
|
"node_modules/express-rate-limit": {
|
|
3135
|
-
"version": "8.5.
|
|
3136
|
-
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.
|
|
3137
|
-
"integrity": "sha512-
|
|
3135
|
+
"version": "8.5.1",
|
|
3136
|
+
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.1.tgz",
|
|
3137
|
+
"integrity": "sha512-5O6KYmyJEpuPJV5hNTXKbAHWRqrzyu+OI3vUnSd2kXFubIVpG7ezpgxQy76Zo5GQZtrQBg86hF+CM/NX+cioiQ==",
|
|
3138
3138
|
"license": "MIT",
|
|
3139
3139
|
"dependencies": {
|
|
3140
|
-
"ip-address": "10.
|
|
3140
|
+
"ip-address": "^10.2.0"
|
|
3141
3141
|
},
|
|
3142
3142
|
"engines": {
|
|
3143
3143
|
"node": ">= 16"
|
|
@@ -3750,9 +3750,9 @@
|
|
|
3750
3750
|
"license": "Apache-2.0 OR MIT"
|
|
3751
3751
|
},
|
|
3752
3752
|
"node_modules/ip-address": {
|
|
3753
|
-
"version": "10.
|
|
3754
|
-
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.
|
|
3755
|
-
"integrity": "sha512
|
|
3753
|
+
"version": "10.2.0",
|
|
3754
|
+
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
|
|
3755
|
+
"integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==",
|
|
3756
3756
|
"license": "MIT",
|
|
3757
3757
|
"engines": {
|
|
3758
3758
|
"node": ">= 12"
|
|
@@ -4930,9 +4930,9 @@
|
|
|
4930
4930
|
}
|
|
4931
4931
|
},
|
|
4932
4932
|
"node_modules/node-abi": {
|
|
4933
|
-
"version": "3.
|
|
4934
|
-
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.
|
|
4935
|
-
"integrity": "sha512-
|
|
4933
|
+
"version": "3.92.0",
|
|
4934
|
+
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.92.0.tgz",
|
|
4935
|
+
"integrity": "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==",
|
|
4936
4936
|
"license": "MIT",
|
|
4937
4937
|
"dependencies": {
|
|
4938
4938
|
"semver": "^7.3.5"
|
package/package.json
CHANGED