open-agents-ai 0.184.70 → 0.184.71
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 +124 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11949,7 +11949,7 @@ function formatTime(seconds) {
|
|
|
11949
11949
|
const s = Math.floor(seconds % 60);
|
|
11950
11950
|
return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
|
|
11951
11951
|
}
|
|
11952
|
-
var AUDIO_EXTS, VIDEO_EXTS, _tcModule, _tcChecked, TranscribeFileTool, TranscribeUrlTool;
|
|
11952
|
+
var AUDIO_EXTS, VIDEO_EXTS, _tcModule, _tcChecked, TranscribeFileTool, TranscribeUrlTool, YouTubeDownloadTool;
|
|
11953
11953
|
var init_transcribe_tool = __esm({
|
|
11954
11954
|
"packages/execution/dist/tools/transcribe-tool.js"() {
|
|
11955
11955
|
"use strict";
|
|
@@ -12267,6 +12267,90 @@ ${result.output}`,
|
|
|
12267
12267
|
}
|
|
12268
12268
|
}
|
|
12269
12269
|
};
|
|
12270
|
+
YouTubeDownloadTool = class {
|
|
12271
|
+
name = "youtube_download";
|
|
12272
|
+
description = "Download video or audio from YouTube. Saves mp4 (video) or mp3 (audio) to the working directory. Uses yt-dlp (auto-installed). Supports youtube.com/watch, youtu.be, shorts, live URLs.";
|
|
12273
|
+
parameters = {
|
|
12274
|
+
type: "object",
|
|
12275
|
+
properties: {
|
|
12276
|
+
url: {
|
|
12277
|
+
type: "string",
|
|
12278
|
+
description: "YouTube URL (youtube.com/watch?v=..., youtu.be/..., etc.)"
|
|
12279
|
+
},
|
|
12280
|
+
format: {
|
|
12281
|
+
type: "string",
|
|
12282
|
+
enum: ["mp3", "mp4"],
|
|
12283
|
+
description: "Output format: 'mp3' for audio only, 'mp4' for video (default: mp3)"
|
|
12284
|
+
},
|
|
12285
|
+
output_dir: {
|
|
12286
|
+
type: "string",
|
|
12287
|
+
description: "Directory to save the file (default: current working directory)"
|
|
12288
|
+
}
|
|
12289
|
+
},
|
|
12290
|
+
required: ["url"]
|
|
12291
|
+
};
|
|
12292
|
+
workingDir;
|
|
12293
|
+
constructor(workingDir) {
|
|
12294
|
+
this.workingDir = workingDir;
|
|
12295
|
+
}
|
|
12296
|
+
async execute(args) {
|
|
12297
|
+
const start = Date.now();
|
|
12298
|
+
const url = String(args.url ?? "").trim();
|
|
12299
|
+
const format = String(args.format ?? "mp3").toLowerCase();
|
|
12300
|
+
const outputDir = String(args.output_dir ?? this.workingDir);
|
|
12301
|
+
if (!url) {
|
|
12302
|
+
return { success: false, output: "", error: "URL is required", durationMs: Date.now() - start };
|
|
12303
|
+
}
|
|
12304
|
+
if (!isYouTubeUrl(url)) {
|
|
12305
|
+
return { success: false, output: "", error: "Not a recognized YouTube URL. Supported: youtube.com/watch, youtu.be, shorts, live, embed", durationMs: Date.now() - start };
|
|
12306
|
+
}
|
|
12307
|
+
if (!ensureYtDlp()) {
|
|
12308
|
+
return { success: false, output: "", error: "yt-dlp not available and auto-install failed. Install manually: pip install yt-dlp", durationMs: Date.now() - start };
|
|
12309
|
+
}
|
|
12310
|
+
mkdirSync7(outputDir, { recursive: true });
|
|
12311
|
+
try {
|
|
12312
|
+
let title = "download";
|
|
12313
|
+
try {
|
|
12314
|
+
title = execSync10(`yt-dlp --get-title "${url}"`, { timeout: 15e3, stdio: "pipe" }).toString().trim().replace(/[<>:"/\\|?*]/g, "_").slice(0, 100);
|
|
12315
|
+
} catch {
|
|
12316
|
+
}
|
|
12317
|
+
if (format === "mp4") {
|
|
12318
|
+
const outPath = join19(outputDir, `${title}.mp4`);
|
|
12319
|
+
const outTemplate = join19(outputDir, `${title}.%(ext)s`);
|
|
12320
|
+
execSync10(`yt-dlp -f "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best" --merge-output-format mp4 -o "${outTemplate}" "${url}"`, { timeout: 6e5, stdio: "pipe", cwd: outputDir });
|
|
12321
|
+
const actualPath = existsSync16(outPath) ? outPath : outTemplate.replace("%(ext)s", "mp4");
|
|
12322
|
+
return {
|
|
12323
|
+
success: true,
|
|
12324
|
+
output: `Downloaded video: ${actualPath}
|
|
12325
|
+
Title: ${title}
|
|
12326
|
+
Format: mp4`,
|
|
12327
|
+
durationMs: Date.now() - start
|
|
12328
|
+
};
|
|
12329
|
+
} else {
|
|
12330
|
+
const outPath = join19(outputDir, `${title}.mp3`);
|
|
12331
|
+
const outTemplate = join19(outputDir, `${title}.%(ext)s`);
|
|
12332
|
+
execSync10(`yt-dlp -x --audio-format mp3 --audio-quality 0 -o "${outTemplate}" "${url}"`, { timeout: 6e5, stdio: "pipe", cwd: outputDir });
|
|
12333
|
+
const actualPath = existsSync16(outPath) ? outPath : outTemplate.replace("%(ext)s", "mp3");
|
|
12334
|
+
return {
|
|
12335
|
+
success: true,
|
|
12336
|
+
output: `Downloaded audio: ${actualPath}
|
|
12337
|
+
Title: ${title}
|
|
12338
|
+
Format: mp3`,
|
|
12339
|
+
durationMs: Date.now() - start
|
|
12340
|
+
};
|
|
12341
|
+
}
|
|
12342
|
+
} catch (err) {
|
|
12343
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12344
|
+
const stderr = err?.stderr?.toString?.()?.slice(0, 500) ?? "";
|
|
12345
|
+
return {
|
|
12346
|
+
success: false,
|
|
12347
|
+
output: "",
|
|
12348
|
+
error: `YouTube download failed: ${msg}${stderr ? "\n" + stderr : ""}`,
|
|
12349
|
+
durationMs: Date.now() - start
|
|
12350
|
+
};
|
|
12351
|
+
}
|
|
12352
|
+
}
|
|
12353
|
+
};
|
|
12270
12354
|
}
|
|
12271
12355
|
});
|
|
12272
12356
|
|
|
@@ -22603,6 +22687,7 @@ __export(dist_exports, {
|
|
|
22603
22687
|
WebFetchTool: () => WebFetchTool,
|
|
22604
22688
|
WebSearchTool: () => WebSearchTool,
|
|
22605
22689
|
WorkingNotesTool: () => WorkingNotesTool,
|
|
22690
|
+
YouTubeDownloadTool: () => YouTubeDownloadTool,
|
|
22606
22691
|
applyPatch: () => applyPatch,
|
|
22607
22692
|
buildCompactDiff: () => buildCompactDiff,
|
|
22608
22693
|
buildCustomTools: () => buildCustomTools,
|
|
@@ -45959,26 +46044,45 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
45959
46044
|
const isArm = process.arch === "arm64" || process.arch === "arm";
|
|
45960
46045
|
if (isArm) {
|
|
45961
46046
|
renderInfo(" ARM device detected \u2014 installing build prerequisites then deps individually.");
|
|
46047
|
+
const isMac = process.platform === "darwin";
|
|
45962
46048
|
try {
|
|
45963
46049
|
const { spawnSync } = await import("node:child_process");
|
|
45964
|
-
|
|
45965
|
-
|
|
45966
|
-
|
|
45967
|
-
|
|
45968
|
-
|
|
45969
|
-
|
|
45970
|
-
|
|
45971
|
-
|
|
45972
|
-
"--
|
|
45973
|
-
|
|
45974
|
-
|
|
45975
|
-
|
|
45976
|
-
|
|
45977
|
-
"
|
|
45978
|
-
"
|
|
45979
|
-
|
|
46050
|
+
if (isMac) {
|
|
46051
|
+
renderInfo(" macOS ARM detected \u2014 installing build deps via Homebrew...");
|
|
46052
|
+
const brewCheck = spawnSync("which", ["brew"], { stdio: "pipe", timeout: 5e3 });
|
|
46053
|
+
if (brewCheck.status === 0) {
|
|
46054
|
+
spawnSync("brew", ["install", "llvm", "gcc", "openblas", "libsndfile"], {
|
|
46055
|
+
stdio: "inherit",
|
|
46056
|
+
timeout: 3e5
|
|
46057
|
+
});
|
|
46058
|
+
const llvmPrefix = spawnSync("brew", ["--prefix", "llvm"], { stdio: "pipe", timeout: 5e3 });
|
|
46059
|
+
if (llvmPrefix.stdout) {
|
|
46060
|
+
process.env.LLVM_CONFIG = `${llvmPrefix.stdout.toString().trim()}/bin/llvm-config`;
|
|
46061
|
+
}
|
|
46062
|
+
} else {
|
|
46063
|
+
renderWarning(" Homebrew not found. Install it: https://brew.sh");
|
|
46064
|
+
renderWarning(" Then run: brew install llvm gcc openblas libsndfile");
|
|
46065
|
+
}
|
|
45980
46066
|
} else {
|
|
45981
|
-
|
|
46067
|
+
renderInfo(" System build tools needed (llvm, gcc). Requesting sudo access...");
|
|
46068
|
+
const sudoCheck = spawnSync("sudo", ["-v"], { stdio: "inherit", timeout: 6e4 });
|
|
46069
|
+
if (sudoCheck.status === 0) {
|
|
46070
|
+
renderInfo(" Installing system build dependencies (this may take a minute)...");
|
|
46071
|
+
spawnSync("sudo", [
|
|
46072
|
+
"apt-get",
|
|
46073
|
+
"install",
|
|
46074
|
+
"-y",
|
|
46075
|
+
"--no-install-recommends",
|
|
46076
|
+
"llvm-dev",
|
|
46077
|
+
"gcc",
|
|
46078
|
+
"g++",
|
|
46079
|
+
"gfortran",
|
|
46080
|
+
"libopenblas-dev",
|
|
46081
|
+
"libsndfile1-dev"
|
|
46082
|
+
], { stdio: "inherit", timeout: 12e4 });
|
|
46083
|
+
} else {
|
|
46084
|
+
renderWarning(" sudo not available \u2014 skipping system build deps. librosa/lhotse may fail to compile.");
|
|
46085
|
+
}
|
|
45982
46086
|
}
|
|
45983
46087
|
} catch (err) {
|
|
45984
46088
|
renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -63749,9 +63853,10 @@ function buildTools(repoRoot, config, contextWindowSize) {
|
|
|
63749
63853
|
// Skill system (AIWG skills — discovery and execution)
|
|
63750
63854
|
new SkillListTool(repoRoot),
|
|
63751
63855
|
new SkillExecuteTool(repoRoot),
|
|
63752
|
-
// Transcription tools (transcribe-cli / faster-whisper)
|
|
63856
|
+
// Transcription + media download tools (transcribe-cli / faster-whisper / yt-dlp)
|
|
63753
63857
|
new TranscribeFileTool(repoRoot),
|
|
63754
63858
|
new TranscribeUrlTool(repoRoot),
|
|
63859
|
+
new YouTubeDownloadTool(repoRoot),
|
|
63755
63860
|
// Structured file generation (CSV, JSON, Markdown, Excel-compatible)
|
|
63756
63861
|
new StructuredFileTool(repoRoot),
|
|
63757
63862
|
// Code sandbox (isolated code execution)
|
package/package.json
CHANGED