@elizaos/plugin-browser 1.0.0-alpha.63 → 1.0.0-alpha.64
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/README.md +64 -64
- package/dist/index.js +17 -50
- package/dist/index.js.map +1 -1
- package/package.json +59 -56
- package/scripts/postinstall.js +47 -50
- package/tsup.config.ts +20 -20
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ AWS_S3_FORCE_PATH_STYLE=boolean(true|false)
|
|
|
62
62
|
## Usage
|
|
63
63
|
|
|
64
64
|
```typescript
|
|
65
|
-
import { createNodePlugin } from
|
|
65
|
+
import { createNodePlugin } from '@elizaos/plugin-node';
|
|
66
66
|
|
|
67
67
|
// Initialize the plugin
|
|
68
68
|
const nodePlugin = createNodePlugin();
|
|
@@ -157,8 +157,8 @@ Analyzes and generates descriptions for images.
|
|
|
157
157
|
|
|
158
158
|
```typescript
|
|
159
159
|
// Example usage
|
|
160
|
-
const result = await runtime.executeAction(
|
|
161
|
-
|
|
160
|
+
const result = await runtime.executeAction('DESCRIBE_IMAGE', {
|
|
161
|
+
imageUrl: 'path/to/image.jpg',
|
|
162
162
|
});
|
|
163
163
|
```
|
|
164
164
|
|
|
@@ -234,7 +234,7 @@ Error: AWS credentials not configured
|
|
|
234
234
|
Enable debug logging for detailed troubleshooting:
|
|
235
235
|
|
|
236
236
|
```typescript
|
|
237
|
-
process.env.DEBUG =
|
|
237
|
+
process.env.DEBUG = 'eliza:plugin-node:*';
|
|
238
238
|
```
|
|
239
239
|
|
|
240
240
|
### System Requirements
|
|
@@ -248,20 +248,20 @@ process.env.DEBUG = "eliza:plugin-node:*";
|
|
|
248
248
|
|
|
249
249
|
1. **Cache Management**
|
|
250
250
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
251
|
+
- Regular cleanup of `content_cache` directory
|
|
252
|
+
- Implement cache size limits
|
|
253
|
+
- Monitor disk usage
|
|
254
254
|
|
|
255
255
|
2. **Memory Usage**
|
|
256
256
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
257
|
+
- Configure max buffer sizes
|
|
258
|
+
- Implement streaming for large files
|
|
259
|
+
- Monitor memory consumption
|
|
260
260
|
|
|
261
261
|
3. **Concurrent Operations**
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
262
|
+
- Adjust queue size limits
|
|
263
|
+
- Configure worker threads
|
|
264
|
+
- Monitor process pool
|
|
265
265
|
|
|
266
266
|
## Support
|
|
267
267
|
|
|
@@ -270,82 +270,82 @@ For issues and feature requests, please:
|
|
|
270
270
|
1. Check the troubleshooting guide above
|
|
271
271
|
2. Review existing GitHub issues
|
|
272
272
|
3. Submit a new issue with:
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
273
|
+
- System information
|
|
274
|
+
- Error logs
|
|
275
|
+
- Steps to reproduce
|
|
276
276
|
|
|
277
277
|
## Future Enhancements
|
|
278
278
|
|
|
279
279
|
1. **File Operations**
|
|
280
280
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
281
|
+
- Enhanced streaming capabilities
|
|
282
|
+
- Advanced compression options
|
|
283
|
+
- Batch file processing
|
|
284
|
+
- File type detection
|
|
285
|
+
- Metadata management
|
|
286
|
+
- Version control integration
|
|
287
287
|
|
|
288
288
|
2. **Media Processing**
|
|
289
289
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
290
|
+
- Additional video formats
|
|
291
|
+
- Advanced image processing
|
|
292
|
+
- Audio enhancement tools
|
|
293
|
+
- Real-time processing
|
|
294
|
+
- Quality optimization
|
|
295
|
+
- Format conversion
|
|
296
296
|
|
|
297
297
|
3. **Cloud Integration**
|
|
298
298
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
299
|
+
- Multi-cloud support
|
|
300
|
+
- Advanced caching
|
|
301
|
+
- CDN optimization
|
|
302
|
+
- Auto-scaling features
|
|
303
|
+
- Cost optimization
|
|
304
|
+
- Backup automation
|
|
305
305
|
|
|
306
306
|
4. **Speech Services**
|
|
307
307
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
308
|
+
- Additional voice models
|
|
309
|
+
- Language expansion
|
|
310
|
+
- Emotion detection
|
|
311
|
+
- Voice cloning
|
|
312
|
+
- Real-time synthesis
|
|
313
|
+
- Custom voice training
|
|
314
314
|
|
|
315
315
|
5. **Browser Automation**
|
|
316
316
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
317
|
+
- Headless optimization
|
|
318
|
+
- Parallel processing
|
|
319
|
+
- Session management
|
|
320
|
+
- Cookie handling
|
|
321
|
+
- Proxy support
|
|
322
|
+
- Resource optimization
|
|
323
323
|
|
|
324
324
|
6. **Security Features**
|
|
325
325
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
326
|
+
- Enhanced encryption
|
|
327
|
+
- Access control
|
|
328
|
+
- Audit logging
|
|
329
|
+
- Threat detection
|
|
330
|
+
- Rate limiting
|
|
331
|
+
- Compliance tools
|
|
332
332
|
|
|
333
333
|
7. **Performance Optimization**
|
|
334
334
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
335
|
+
- Memory management
|
|
336
|
+
- CPU utilization
|
|
337
|
+
- Concurrent operations
|
|
338
|
+
- Resource pooling
|
|
339
|
+
- Cache strategies
|
|
340
|
+
- Load balancing
|
|
341
341
|
|
|
342
342
|
8. **Developer Tools**
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
343
|
+
- Enhanced debugging
|
|
344
|
+
- Testing framework
|
|
345
|
+
- Documentation generator
|
|
346
|
+
- CLI improvements
|
|
347
|
+
- Monitoring tools
|
|
348
|
+
- Integration templates
|
|
349
349
|
|
|
350
350
|
We welcome community feedback and contributions to help prioritize these enhancements.
|
|
351
351
|
|
package/dist/index.js
CHANGED
|
@@ -270,11 +270,7 @@ var require_src2 = __commonJS({
|
|
|
270
270
|
// src/services/awsS3.ts
|
|
271
271
|
import fs from "node:fs";
|
|
272
272
|
import path from "node:path";
|
|
273
|
-
import {
|
|
274
|
-
GetObjectCommand,
|
|
275
|
-
PutObjectCommand,
|
|
276
|
-
S3Client
|
|
277
|
-
} from "@aws-sdk/client-s3";
|
|
273
|
+
import { GetObjectCommand, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
|
278
274
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
279
275
|
import {
|
|
280
276
|
Service,
|
|
@@ -341,9 +337,7 @@ var AwsS3Service = class _AwsS3Service extends Service {
|
|
|
341
337
|
if (this.s3Client) return true;
|
|
342
338
|
if (!this.runtime) return false;
|
|
343
339
|
const AWS_ACCESS_KEY_ID = this.runtime.getSetting("AWS_ACCESS_KEY_ID");
|
|
344
|
-
const AWS_SECRET_ACCESS_KEY = this.runtime.getSetting(
|
|
345
|
-
"AWS_SECRET_ACCESS_KEY"
|
|
346
|
-
);
|
|
340
|
+
const AWS_SECRET_ACCESS_KEY = this.runtime.getSetting("AWS_SECRET_ACCESS_KEY");
|
|
347
341
|
const AWS_REGION = this.runtime.getSetting("AWS_REGION");
|
|
348
342
|
const AWS_S3_BUCKET = this.runtime.getSetting("AWS_S3_BUCKET");
|
|
349
343
|
if (!AWS_ACCESS_KEY_ID || !AWS_SECRET_ACCESS_KEY || !AWS_REGION || !AWS_S3_BUCKET) {
|
|
@@ -536,14 +530,11 @@ import {
|
|
|
536
530
|
ServiceType as ServiceType2,
|
|
537
531
|
logger as logger2,
|
|
538
532
|
parseJSONObjectFromText,
|
|
539
|
-
settings,
|
|
540
533
|
stringToUuid,
|
|
541
534
|
trimTokens
|
|
542
535
|
} from "@elizaos/core";
|
|
543
536
|
import CaptchaSolver from "capsolver-npm";
|
|
544
|
-
import {
|
|
545
|
-
chromium
|
|
546
|
-
} from "patchright";
|
|
537
|
+
import { chromium } from "patchright";
|
|
547
538
|
async function generateSummary(runtime, text) {
|
|
548
539
|
text = await trimTokens(text, 1e5, runtime);
|
|
549
540
|
const prompt = `Please generate a concise summary for the following text:
|
|
@@ -590,7 +581,7 @@ var BrowserService = class _BrowserService extends Service2 {
|
|
|
590
581
|
this.runtime = runtime;
|
|
591
582
|
this.browser = void 0;
|
|
592
583
|
this.context = void 0;
|
|
593
|
-
this.captchaSolver = new CaptchaSolver(
|
|
584
|
+
this.captchaSolver = new CaptchaSolver(runtime.getSetting("CAPSOLVER_API_KEY") || "");
|
|
594
585
|
}
|
|
595
586
|
/**
|
|
596
587
|
* Starts the BrowserService asynchronously.
|
|
@@ -699,9 +690,7 @@ var BrowserService = class _BrowserService extends Service2 {
|
|
|
699
690
|
let page;
|
|
700
691
|
try {
|
|
701
692
|
if (!this.context) {
|
|
702
|
-
logger2.log(
|
|
703
|
-
"Browser context not initialized. Call initializeBrowser() first."
|
|
704
|
-
);
|
|
693
|
+
logger2.log("Browser context not initialized. Call initializeBrowser() first.");
|
|
705
694
|
}
|
|
706
695
|
page = await this.context.newPage();
|
|
707
696
|
await page.setExtraHTTPHeaders({
|
|
@@ -805,9 +794,7 @@ ${bodyContent}`
|
|
|
805
794
|
*/
|
|
806
795
|
async getHCaptchaWebsiteKey(page) {
|
|
807
796
|
return page.evaluate(() => {
|
|
808
|
-
const hcaptchaIframe = document.querySelector(
|
|
809
|
-
'iframe[src*="hcaptcha.com"]'
|
|
810
|
-
);
|
|
797
|
+
const hcaptchaIframe = document.querySelector('iframe[src*="hcaptcha.com"]');
|
|
811
798
|
if (hcaptchaIframe) {
|
|
812
799
|
const src = hcaptchaIframe.getAttribute("src");
|
|
813
800
|
const match = src?.match(/sitekey=([^&]*)/);
|
|
@@ -844,9 +831,7 @@ ${bodyContent}`
|
|
|
844
831
|
}
|
|
845
832
|
}
|
|
846
833
|
if (!url.match(/www.google.com\/search/)) {
|
|
847
|
-
const googleSearchUrl = `https://www.google.com/search?q=${encodeURIComponent(
|
|
848
|
-
url
|
|
849
|
-
)}`;
|
|
834
|
+
const googleSearchUrl = `https://www.google.com/search?q=${encodeURIComponent(url)}`;
|
|
850
835
|
try {
|
|
851
836
|
return await this.fetchPageContent(googleSearchUrl, runtime);
|
|
852
837
|
} catch (error) {
|
|
@@ -1121,14 +1106,13 @@ var VideoService = class _VideoService extends Service4 {
|
|
|
1121
1106
|
const cacheKey = `${this.cacheKey}/${videoUuid}`;
|
|
1122
1107
|
const cached = await runtime.getCache(cacheKey);
|
|
1123
1108
|
if (cached) {
|
|
1124
|
-
logger3.
|
|
1109
|
+
logger3.debug("Returning cached video file");
|
|
1125
1110
|
return cached;
|
|
1126
1111
|
}
|
|
1127
1112
|
try {
|
|
1128
|
-
logger3.
|
|
1129
|
-
logger3.log("Fetching video info");
|
|
1113
|
+
logger3.debug("Fetching video info");
|
|
1130
1114
|
const videoInfo = await this.fetchVideoInfo(url);
|
|
1131
|
-
|
|
1115
|
+
logger3.debug("Getting transcript");
|
|
1132
1116
|
const transcript = await this.getTranscript(url, videoInfo, runtime);
|
|
1133
1117
|
const result = {
|
|
1134
1118
|
id: videoUuid,
|
|
@@ -1159,7 +1143,6 @@ var VideoService = class _VideoService extends Service4 {
|
|
|
1159
1143
|
* @returns {Promise<any>} A Promise resolving to the fetched video information or rejecting with an error message
|
|
1160
1144
|
*/
|
|
1161
1145
|
async fetchVideoInfo(url) {
|
|
1162
|
-
console.log("url", url);
|
|
1163
1146
|
if (url.endsWith(".mp4") || url.includes(".mp4?")) {
|
|
1164
1147
|
try {
|
|
1165
1148
|
const response = await fetch(url);
|
|
@@ -1192,9 +1175,7 @@ var VideoService = class _VideoService extends Service4 {
|
|
|
1192
1175
|
}
|
|
1193
1176
|
return result;
|
|
1194
1177
|
} catch (error) {
|
|
1195
|
-
throw new Error(
|
|
1196
|
-
`Failed to fetch video information: ${error.message || error}`
|
|
1197
|
-
);
|
|
1178
|
+
throw new Error(`Failed to fetch video information: ${error.message || error}`);
|
|
1198
1179
|
}
|
|
1199
1180
|
}
|
|
1200
1181
|
/**
|
|
@@ -1210,9 +1191,7 @@ var VideoService = class _VideoService extends Service4 {
|
|
|
1210
1191
|
try {
|
|
1211
1192
|
if (videoInfo.subtitles?.en) {
|
|
1212
1193
|
logger3.log("Manual subtitles found");
|
|
1213
|
-
const srtContent = await this.downloadSRT(
|
|
1214
|
-
videoInfo.subtitles.en[0].url
|
|
1215
|
-
);
|
|
1194
|
+
const srtContent = await this.downloadSRT(videoInfo.subtitles.en[0].url);
|
|
1216
1195
|
return this.parseSRT(srtContent);
|
|
1217
1196
|
}
|
|
1218
1197
|
if (videoInfo.automatic_captions?.en) {
|
|
@@ -1225,9 +1204,7 @@ var VideoService = class _VideoService extends Service4 {
|
|
|
1225
1204
|
logger3.log("Music video detected, no lyrics available");
|
|
1226
1205
|
return "No lyrics available.";
|
|
1227
1206
|
}
|
|
1228
|
-
logger3.log(
|
|
1229
|
-
"No subtitles or captions found, falling back to audio transcription"
|
|
1230
|
-
);
|
|
1207
|
+
logger3.log("No subtitles or captions found, falling back to audio transcription");
|
|
1231
1208
|
return this.transcribeAudio(url, runtime);
|
|
1232
1209
|
} catch (error) {
|
|
1233
1210
|
logger3.log("Error in getTranscript:", error);
|
|
@@ -1309,10 +1286,7 @@ var VideoService = class _VideoService extends Service4 {
|
|
|
1309
1286
|
return null;
|
|
1310
1287
|
}
|
|
1311
1288
|
const mp4FilePath = path2.join(this.dataDir, `${this.getVideoId(url)}.mp4`);
|
|
1312
|
-
const webmFilePath = path2.join(
|
|
1313
|
-
this.dataDir,
|
|
1314
|
-
`${this.getVideoId(url)}.webm`
|
|
1315
|
-
);
|
|
1289
|
+
const webmFilePath = path2.join(this.dataDir, `${this.getVideoId(url)}.webm`);
|
|
1316
1290
|
const mp3FilePath = path2.join(this.dataDir, `${this.getVideoId(url)}.mp3`);
|
|
1317
1291
|
if (!fs2.existsSync(mp3FilePath)) {
|
|
1318
1292
|
if (fs2.existsSync(webmFilePath)) {
|
|
@@ -1331,14 +1305,9 @@ var VideoService = class _VideoService extends Service4 {
|
|
|
1331
1305
|
logger3.log(`Audio file size: ${audioBuffer.length} bytes`);
|
|
1332
1306
|
logger3.log("Starting transcription...");
|
|
1333
1307
|
const startTime = Date.now();
|
|
1334
|
-
const transcript = await runtime.useModel(
|
|
1335
|
-
ModelType2.TRANSCRIPTION,
|
|
1336
|
-
audioBuffer
|
|
1337
|
-
);
|
|
1308
|
+
const transcript = await runtime.useModel(ModelType2.TRANSCRIPTION, audioBuffer);
|
|
1338
1309
|
const endTime = Date.now();
|
|
1339
|
-
logger3.log(
|
|
1340
|
-
`Transcription completed in ${(endTime - startTime) / 1e3} seconds`
|
|
1341
|
-
);
|
|
1310
|
+
logger3.log(`Transcription completed in ${(endTime - startTime) / 1e3} seconds`);
|
|
1342
1311
|
return transcript || "Transcription failed";
|
|
1343
1312
|
}
|
|
1344
1313
|
/**
|
|
@@ -1392,9 +1361,7 @@ var VideoService = class _VideoService extends Service4 {
|
|
|
1392
1361
|
outputFile = outputFile ?? path2.join(this.dataDir, `${this.getVideoId(url)}.mp3`);
|
|
1393
1362
|
try {
|
|
1394
1363
|
if (url.endsWith(".mp4") || url.includes(".mp4?")) {
|
|
1395
|
-
logger3.log(
|
|
1396
|
-
"Direct MP4 file detected, downloading and converting to MP3"
|
|
1397
|
-
);
|
|
1364
|
+
logger3.log("Direct MP4 file detected, downloading and converting to MP3");
|
|
1398
1365
|
const tempMp4File = path2.join(tmpdir(), `${this.getVideoId(url)}.mp4`);
|
|
1399
1366
|
const response = await fetch(url);
|
|
1400
1367
|
const arrayBuffer = await response.arrayBuffer();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../node_modules/dargs/index.js","../../../node_modules/tinyspawn/src/index.js","../../../node_modules/is-unix/index.js","../../../node_modules/youtube-dl-exec/src/constants.js","../../../node_modules/youtube-dl-exec/src/index.js","../src/services/awsS3.ts","../src/services/browser.ts","../src/services/pdf.ts","../src/services/video.ts","../src/index.ts"],"sourcesContent":["'use strict';\n\nconst match = (array, value) =>\n\tarray.some(x => (x instanceof RegExp ? x.test(value) : x === value));\n\nconst dargs = (object, options) => {\n\tconst arguments_ = [];\n\tlet extraArguments = [];\n\tlet separatedArguments = [];\n\n\toptions = {\n\t\tuseEquals: true,\n\t\tshortFlag: true,\n\t\t...options\n\t};\n\n\tconst makeArguments = (key, value) => {\n\t\tconst prefix = options.shortFlag && key.length === 1 ? '-' : '--';\n\t\tconst theKey = (options.allowCamelCase ?\n\t\t\tkey :\n\t\t\tkey.replace(/[A-Z]/g, '-$&').toLowerCase());\n\n\t\tkey = prefix + theKey;\n\n\t\tif (options.useEquals) {\n\t\t\targuments_.push(key + (value ? `=${value}` : ''));\n\t\t} else {\n\t\t\targuments_.push(key);\n\n\t\t\tif (value) {\n\t\t\t\targuments_.push(value);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst makeAliasArg = (key, value) => {\n\t\targuments_.push(`-${key}`);\n\n\t\tif (value) {\n\t\t\targuments_.push(value);\n\t\t}\n\t};\n\n\tfor (let [key, value] of Object.entries(object)) {\n\t\tlet pushArguments = makeArguments;\n\n\t\tif (Array.isArray(options.excludes) && match(options.excludes, key)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(options.includes) && !match(options.includes, key)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (typeof options.aliases === 'object' && options.aliases[key]) {\n\t\t\tkey = options.aliases[key];\n\t\t\tpushArguments = makeAliasArg;\n\t\t}\n\n\t\tif (key === '--') {\n\t\t\tif (!Array.isArray(value)) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`Expected key \\`--\\` to be Array, got ${typeof value}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tseparatedArguments = value;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (key === '_') {\n\t\t\tif (!Array.isArray(value)) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`Expected key \\`_\\` to be Array, got ${typeof value}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\textraArguments = value;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (value === true) {\n\t\t\tpushArguments(key, '');\n\t\t}\n\n\t\tif (value === false && !options.ignoreFalse) {\n\t\t\tpushArguments(`no-${key}`);\n\t\t}\n\n\t\tif (typeof value === 'string') {\n\t\t\tpushArguments(key, value);\n\t\t}\n\n\t\tif (typeof value === 'number' && !Number.isNaN(value)) {\n\t\t\tpushArguments(key, String(value));\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const arrayValue of value) {\n\t\t\t\tpushArguments(key, arrayValue);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const argument of extraArguments) {\n\t\targuments_.push(String(argument));\n\t}\n\n\tif (separatedArguments.length > 0) {\n\t\targuments_.push('--');\n\t}\n\n\tfor (const argument of separatedArguments) {\n\t\targuments_.push(String(argument));\n\t}\n\n\treturn arguments_;\n};\n\nmodule.exports = dargs;\n","'use strict'\n\nconst { spawn } = require('child_process')\nconst { EOL } = require('os')\n\nconst EE_PROPS = Object.getOwnPropertyNames(require('events').EventEmitter.prototype)\n .filter(name => !name.startsWith('_'))\n .concat(['kill', 'ref', 'unref'])\n\nconst eos = (stream, listener, buffer = []) =>\n stream[listener] ? stream[listener].on('data', data => buffer.push(data)) && buffer : buffer\n\nconst createChildProcessError = ({ cmd, cmdArgs, childProcess }) => {\n const command = `${cmd} ${cmdArgs.join(' ')}`\n let message = `The command spawned as:${EOL}${EOL}`\n message += ` \\`${command}\\`${EOL}${EOL}`\n message += `exited with:${EOL}${EOL}`\n message += ` \\`{ signal: '${childProcess.signalCode}', code: ${childProcess.exitCode} }\\` ${EOL}${EOL}`\n message += `with the following trace:${EOL}`\n const error = new Error(message)\n error.command = command\n error.name = 'ChildProcessError'\n\n Object.keys(childProcess)\n .filter(key => !key.startsWith('_') && !['stdio', 'stdin'].includes(key))\n .forEach(key => {\n error[key] = childProcess[key]\n })\n\n return error\n}\n\nconst clean = str => str.trim().replace(/\\n$/, '')\n\nconst parse =\n (buffer, { json } = {}) =>\n (encoding, start, end) => {\n const data = clean(Buffer.concat(buffer).toString(encoding, start, end))\n return json ? JSON.parse(data) : data\n }\n\nconst extend = defaults => (input, args, options) => {\n if (!(args instanceof Array)) {\n options = args\n args = []\n }\n const [cmd, ...cmdArgs] = input.split(' ').concat(args).filter(Boolean)\n let childProcess\n\n const promise = new Promise((resolve, reject) => {\n const opts = { ...defaults, ...options }\n childProcess = spawn(cmd, cmdArgs, opts)\n const stdout = eos(childProcess, 'stdout')\n const stderr = eos(childProcess, 'stderr')\n\n childProcess.on('error', reject).on('exit', exitCode => {\n Object.defineProperty(childProcess, 'stdout', {\n get: parse(stdout, opts)\n })\n Object.defineProperty(childProcess, 'stderr', { get: parse(stderr) })\n return exitCode === 0\n ? resolve(childProcess)\n : reject(createChildProcessError({ cmd, cmdArgs, childProcess }))\n })\n })\n\n const subprocess = Object.assign(promise, childProcess)\n if (childProcess) {\n EE_PROPS.forEach(name => (subprocess[name] = childProcess[name].bind(childProcess)))\n }\n return subprocess\n}\n\nconst $ = extend()\n$.extend = extend\n$.json = $.extend({ json: true })\n\nmodule.exports = $\n","'use strict'\n\nmodule.exports = (platform = '') => {\n platform = platform.toLowerCase()\n return (\n [\n 'aix',\n 'android',\n 'darwin',\n 'freebsd',\n 'linux',\n 'openbsd',\n 'sunos'\n ].indexOf(platform) !== -1\n )\n}\n","'use strict'\n\nconst isUnix = require('is-unix')\nconst path = require('path')\n\nconst PLATFORM_WIN = 'win32'\nconst PLATFORM_UNIX = 'unix'\n\nfunction get (key) {\n if (!key) return undefined\n return (\n process.env[key] ??\n process.env[`npm_config_${key.toLowerCase()}`] ??\n process.env[`npm_config_${key.toUpperCase()}`]\n )\n}\n\nconst YOUTUBE_DL_HOST =\n get('YOUTUBE_DL_HOST') ??\n 'https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest'\n\nconst YOUTUBE_DL_DIR =\n get('YOUTUBE_DL_DIR') ?? path.join(__dirname, '..', 'bin')\n\nconst YOUTUBE_DL_PLATFORM =\n get('YOUTUBE_DL_PLATFORM') ?? isUnix(process.platform)\n ? PLATFORM_UNIX\n : PLATFORM_WIN\n\nconst YOUTUBE_DL_FILENAME = get('YOUTUBE_DL_FILENAME') || 'yt-dlp'\n\nconst YOUTUBE_DL_FILE =\n !YOUTUBE_DL_FILENAME.endsWith('.exe') && YOUTUBE_DL_PLATFORM === 'win32'\n ? `${YOUTUBE_DL_FILENAME}.exe`\n : YOUTUBE_DL_FILENAME\n\nconst YOUTUBE_DL_PATH = path.join(YOUTUBE_DL_DIR, YOUTUBE_DL_FILE)\n\nconst YOUTUBE_DL_SKIP_DOWNLOAD = get('YOUTUBE_DL_SKIP_DOWNLOAD')\n\nmodule.exports = {\n YOUTUBE_DL_DIR,\n YOUTUBE_DL_FILE,\n YOUTUBE_DL_FILENAME,\n YOUTUBE_DL_HOST,\n YOUTUBE_DL_PATH,\n YOUTUBE_DL_PLATFORM,\n YOUTUBE_DL_SKIP_DOWNLOAD\n}\n","'use strict'\n\nconst dargs = require('dargs')\nconst $ = require('tinyspawn')\n\nconst constants = require('./constants')\n\nconst args = (flags = {}) => dargs(flags, { useEquals: false }).filter(Boolean)\n\nconst isJSON = (str = '') => str.startsWith('{')\n\nconst parse = ({ stdout, stderr, ...details }) => {\n if (details.exitCode === 0) { return isJSON(stdout) ? JSON.parse(stdout) : stdout }\n throw Object.assign(new Error(stderr), { stderr, stdout }, details)\n}\n\nconst create = binaryPath => {\n const fn = (...args) =>\n fn\n .exec(...args)\n .then(parse)\n .catch(parse)\n fn.exec = (url, flags, opts) => $(binaryPath, [url].concat(args(flags)), opts)\n return fn\n}\n\nconst defaultInstance = create(constants.YOUTUBE_DL_PATH)\n\nmodule.exports = defaultInstance\nmodule.exports.youtubeDl = defaultInstance\nmodule.exports.create = create\nmodule.exports.args = args\nmodule.exports.isJSON = isJSON\nmodule.exports.constants = constants\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n\tGetObjectCommand,\n\tPutObjectCommand,\n\tS3Client,\n} from \"@aws-sdk/client-s3\";\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\nimport {\n\ttype IAgentRuntime,\n\ttype IFileService,\n\tService,\n\ttype ServiceTypeName,\n\tServiceType,\n\tlogger,\n} from \"@elizaos/core\";\n\n/**\n * Interface representing the result of an upload operation.\n * @typedef {Object} UploadResult\n * @property {boolean} success - Indicates if the upload was successful or not.\n * @property {string} [url] - The URL of the uploaded file (optional).\n * @property {string} [error] - The error message in case the upload was unsuccessful (optional).\n */\ninterface UploadResult {\n\tsuccess: boolean;\n\turl?: string;\n\terror?: string;\n}\n\n/**\n * Interface for the result of uploading a JSON file.\n * Extends UploadResult interface.\n *\n * @property {string} [key] - Optional storage key for the uploaded file.\n */\ninterface JsonUploadResult extends UploadResult {\n\tkey?: string; // Add storage key\n}\n\n/**\n * Represents a service for interacting with AWS S3 to upload, download, and manage files.\n * @implements {IFileService}\n */\nexport class AwsS3Service extends Service implements IFileService {\n\tstatic serviceType: ServiceTypeName = ServiceType.REMOTE_FILES;\n\tcapabilityDescription =\n\t\t\"The agent is able to upload and download files from AWS S3\";\n\n\tprivate s3Client: S3Client | null = null;\n\tprivate bucket = \"\";\n\tprivate fileUploadPath = \"\";\n\tprotected runtime: IAgentRuntime | null = null;\n\n\t/**\n\t * Constructor for a new instance of a class.\n\t * @param {IAgentRuntime} runtime - The runtime object for the agent.\n\t */\n\tconstructor(runtime: IAgentRuntime) {\n\t\tsuper();\n\t\tthis.runtime = runtime;\n\t\tthis.fileUploadPath = runtime.getSetting(\"AWS_S3_UPLOAD_PATH\") ?? \"\";\n\t}\n\n\t/**\n\t * Initializes AwsS3Service with the given runtime and settings.\n\t * @param {IAgentRuntime} runtime - The runtime object\n\t * @returns {Promise<AwsS3Service>} - The AwsS3Service instance\n\t */\n\tstatic async start(runtime: IAgentRuntime): Promise<AwsS3Service> {\n\t\tlogger.log(\"Initializing AwsS3Service\");\n\t\tconst service = new AwsS3Service(runtime);\n\t\tservice.runtime = runtime;\n\t\tservice.fileUploadPath = runtime.getSetting(\"AWS_S3_UPLOAD_PATH\") ?? \"\";\n\t\treturn service;\n\t}\n\n\t/**\n\t * Stops the remote file service.\n\t *\n\t * @param {IAgentRuntime} runtime - The agent runtime\n\t * @returns {Promise<void>} - A promise that resolves once the service is stopped\n\t */\n\tstatic async stop(runtime: IAgentRuntime) {\n\t\tconst service = runtime.getService(ServiceType.REMOTE_FILES);\n\t\tif (service) {\n\t\t\tawait service.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously stops the S3 client if it exists by destroying the client and setting it to null.\n\t */\n\tasync stop() {\n\t\tif (this.s3Client) {\n\t\t\tawait this.s3Client.destroy();\n\t\t\tthis.s3Client = null;\n\t\t}\n\t}\n\n\t/**\n\t * Initializes the S3 client with the provided settings.\n\t * If the S3 client is already initialized, it returns true.\n\t * If any required setting is missing or invalid, it returns false.\n\t *\n\t * @returns A Promise that resolves to true if the S3 client is successfully initialized, false otherwise.\n\t */\n\tprivate async initializeS3Client(): Promise<boolean> {\n\t\tif (this.s3Client) return true;\n\t\tif (!this.runtime) return false;\n\n\t\tconst AWS_ACCESS_KEY_ID = this.runtime.getSetting(\"AWS_ACCESS_KEY_ID\");\n\t\tconst AWS_SECRET_ACCESS_KEY = this.runtime.getSetting(\n\t\t\t\"AWS_SECRET_ACCESS_KEY\",\n\t\t);\n\t\tconst AWS_REGION = this.runtime.getSetting(\"AWS_REGION\");\n\t\tconst AWS_S3_BUCKET = this.runtime.getSetting(\"AWS_S3_BUCKET\");\n\n\t\tif (\n\t\t\t!AWS_ACCESS_KEY_ID ||\n\t\t\t!AWS_SECRET_ACCESS_KEY ||\n\t\t\t!AWS_REGION ||\n\t\t\t!AWS_S3_BUCKET\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Optional fields to allow for other providers\n\t\tconst endpoint = this.runtime.getSetting(\"AWS_S3_ENDPOINT\");\n\t\tconst sslEnabled = this.runtime.getSetting(\"AWS_S3_SSL_ENABLED\");\n\t\tconst forcePathStyle = this.runtime.getSetting(\"AWS_S3_FORCE_PATH_STYLE\");\n\n\t\tthis.s3Client = new S3Client({\n\t\t\t...(endpoint ? { endpoint } : {}),\n\t\t\t...(sslEnabled ? { sslEnabled } : {}),\n\t\t\t...(forcePathStyle ? { forcePathStyle: Boolean(forcePathStyle) } : {}),\n\t\t\tregion: AWS_REGION,\n\t\t\tcredentials: {\n\t\t\t\taccessKeyId: AWS_ACCESS_KEY_ID,\n\t\t\t\tsecretAccessKey: AWS_SECRET_ACCESS_KEY,\n\t\t\t},\n\t\t});\n\t\tthis.bucket = AWS_S3_BUCKET;\n\t\treturn true;\n\t}\n\n\t/**\n\t * Uploads a file to AWS S3 with optional configuration options.\n\t * @param {string} filePath - The path to the file to upload.\n\t * @param {string} [subDirectory=\"\"] - The subdirectory within the bucket to upload the file to.\n\t * @param {boolean} [useSignedUrl=false] - Indicates whether to use a signed URL for the file.\n\t * @param {number} [expiresIn=900] - The expiration time in seconds for the signed URL.\n\t * @returns {Promise<UploadResult>} A promise that resolves to an object containing the upload result.\n\t */\n\tasync uploadFile(\n\t\tfilePath: string,\n\t\tsubDirectory = \"\",\n\t\tuseSignedUrl = false,\n\t\texpiresIn = 900,\n\t): Promise<UploadResult> {\n\t\ttry {\n\t\t\tif (!(await this.initializeS3Client())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: \"AWS S3 credentials not configured\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (!fs.existsSync(filePath)) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: \"File does not exist\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst fileContent = fs.readFileSync(filePath);\n\n\t\t\tconst baseFileName = `${Date.now()}-${path.basename(filePath)}`;\n\t\t\t// Determine storage path based on public access\n\t\t\tconst fileName =\n\t\t\t\t`${this.fileUploadPath}${subDirectory}/${baseFileName}`.replaceAll(\n\t\t\t\t\t\"//\",\n\t\t\t\t\t\"/\",\n\t\t\t\t);\n\t\t\t// Set upload parameters\n\t\t\tconst uploadParams = {\n\t\t\t\tBucket: this.bucket,\n\t\t\t\tKey: fileName,\n\t\t\t\tBody: fileContent,\n\t\t\t\tContentType: this.getContentType(filePath),\n\t\t\t};\n\n\t\t\t// Upload file\n\t\t\tawait this.s3Client.send(new PutObjectCommand(uploadParams));\n\n\t\t\t// Build result object\n\t\t\tconst result: UploadResult = {\n\t\t\t\tsuccess: true,\n\t\t\t};\n\n\t\t\t// If not using signed URL, return either custom endpoint or public access URL\n\t\t\tif (!useSignedUrl) {\n\t\t\t\tif (this.s3Client.config.endpoint) {\n\t\t\t\t\tconst endpoint = await this.s3Client.config.endpoint();\n\t\t\t\t\tconst port = endpoint.port ? `:${endpoint.port}` : \"\";\n\t\t\t\t\tresult.url = `${endpoint.protocol}//${endpoint.hostname}${port}${endpoint.path}${this.bucket}/${fileName}`;\n\t\t\t\t} else {\n\t\t\t\t\tresult.url = `https://${this.bucket}.s3.${process.env.AWS_REGION}.amazonaws.com/${fileName}`;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst getObjectCommand = new GetObjectCommand({\n\t\t\t\t\tBucket: this.bucket,\n\t\t\t\t\tKey: fileName,\n\t\t\t\t});\n\t\t\t\tresult.url = await getSignedUrl(this.s3Client, getObjectCommand, {\n\t\t\t\t\texpiresIn, // 15 minutes in seconds\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror:\n\t\t\t\t\terror instanceof Error ? error.message : \"Unknown error occurred\",\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Generate signed URL for existing file\n\t */\n\t/**\n\t * Generates a signed URL for accessing the specified file in the S3 bucket.\n\t *\n\t * @param {string} fileName - The name of the file to generate a signed URL for.\n\t * @param {number} expiresIn - The expiration time in seconds for the signed URL (default is 900 seconds).\n\t * @returns {Promise<string>} A promise that resolves with the signed URL for accessing the file.\n\t * @throws {Error} If AWS S3 credentials are not configured properly.\n\t */\n\tasync generateSignedUrl(fileName: string, expiresIn = 900): Promise<string> {\n\t\tif (!(await this.initializeS3Client())) {\n\t\t\tthrow new Error(\"AWS S3 credentials not configured\");\n\t\t}\n\n\t\tconst command = new GetObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: fileName,\n\t\t});\n\n\t\treturn await getSignedUrl(this.s3Client, command, { expiresIn });\n\t}\n\n\tprivate getContentType(filePath: string): string {\n\t\tconst ext = path.extname(filePath).toLowerCase();\n\t\tconst contentTypes: { [key: string]: string } = {\n\t\t\t\".png\": \"image/png\",\n\t\t\t\".jpg\": \"image/jpeg\",\n\t\t\t\".jpeg\": \"image/jpeg\",\n\t\t\t\".gif\": \"image/gif\",\n\t\t\t\".webp\": \"image/webp\",\n\t\t};\n\t\treturn contentTypes[ext] || \"application/octet-stream\";\n\t}\n\n\t/**\n\t * Upload JSON object to S3\n\t * @param jsonData JSON data to upload\n\t * @param fileName File name (optional, without path)\n\t * @param subDirectory Subdirectory (optional)\n\t * @param useSignedUrl Whether to use signed URL\n\t * @param expiresIn Signed URL expiration time (seconds)\n\t */\n\tasync uploadJson(\n\t\tjsonData: any,\n\t\tfileName?: string,\n\t\tsubDirectory?: string,\n\t\tuseSignedUrl = false,\n\t\texpiresIn = 900,\n\t): Promise<JsonUploadResult> {\n\t\ttry {\n\t\t\tif (!(await this.initializeS3Client())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: \"AWS S3 credentials not configured\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Validate input\n\t\t\tif (!jsonData) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: \"JSON data is required\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Generate filename (if not provided)\n\t\t\tconst timestamp = Date.now();\n\t\t\tconst actualFileName = fileName || `${timestamp}.json`;\n\n\t\t\t// Build complete file path\n\t\t\tlet fullPath = this.fileUploadPath || \"\";\n\t\t\tif (subDirectory) {\n\t\t\t\tfullPath = `${fullPath}/${subDirectory}`.replace(/\\/+/g, \"/\");\n\t\t\t}\n\t\t\tconst key = `${fullPath}/${actualFileName}`.replace(/\\/+/g, \"/\");\n\n\t\t\t// Convert JSON to string\n\t\t\tconst jsonString = JSON.stringify(jsonData, null, 2);\n\n\t\t\t// Set upload parameters\n\t\t\tconst uploadParams = {\n\t\t\t\tBucket: this.bucket,\n\t\t\t\tKey: key,\n\t\t\t\tBody: jsonString,\n\t\t\t\tContentType: \"application/json\",\n\t\t\t};\n\n\t\t\t// Upload file\n\t\t\tawait this.s3Client.send(new PutObjectCommand(uploadParams));\n\n\t\t\t// Build result\n\t\t\tconst result: JsonUploadResult = {\n\t\t\t\tsuccess: true,\n\t\t\t\tkey: key,\n\t\t\t};\n\n\t\t\t// If not using signed URL, return either custom endpoint or public access URL\n\t\t\tif (!useSignedUrl) {\n\t\t\t\tif (this.s3Client.config.endpoint) {\n\t\t\t\t\tconst endpoint = await this.s3Client.config.endpoint();\n\t\t\t\t\tconst port = endpoint.port ? `:${endpoint.port}` : \"\";\n\t\t\t\t\tresult.url = `${endpoint.protocol}//${endpoint.hostname}${port}${endpoint.path}${this.bucket}/${key}`;\n\t\t\t\t} else {\n\t\t\t\t\tresult.url = `https://${this.bucket}.s3.${process.env.AWS_REGION}.amazonaws.com/${key}`;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst getObjectCommand = new GetObjectCommand({\n\t\t\t\t\tBucket: this.bucket,\n\t\t\t\t\tKey: key,\n\t\t\t\t});\n\t\t\t\tresult.url = await getSignedUrl(this.s3Client, getObjectCommand, {\n\t\t\t\t\texpiresIn,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror:\n\t\t\t\t\terror instanceof Error ? error.message : \"Unknown error occurred\",\n\t\t\t};\n\t\t}\n\t}\n}\n\nexport default AwsS3Service;\n","import {\n\ttype IAgentRuntime,\n\ttype IBrowserService,\n\tModelType,\n\tService,\n\ttype ServiceTypeName,\n\tServiceType,\n\tlogger,\n\tparseJSONObjectFromText,\n\tsettings,\n\tstringToUuid,\n\ttrimTokens,\n} from \"@elizaos/core\";\nimport CaptchaSolver from \"capsolver-npm\";\nimport {\n\ttype Browser,\n\ttype BrowserContext,\n\ttype Page,\n\tchromium,\n} from \"patchright\";\n\n/**\n * Asynchronously generates a summary for a given text using a machine learning model.\n *\n * @param {IAgentRuntime} runtime - The runtime environment for the agent\n * @param {string} text - The text to generate a summary for\n * @returns {Promise<{ title: string; description: string }>} A promise that resolves to an object containing the generated title and summary\n */\nasync function generateSummary(\n\truntime: IAgentRuntime,\n\ttext: string,\n): Promise<{ title: string; description: string }> {\n\t// make sure text is under 128k characters\n\ttext = await trimTokens(text, 100000, runtime);\n\n\tconst prompt = `Please generate a concise summary for the following text:\n\n Text: \"\"\"\n ${text}\n \"\"\"\n\n Respond with a JSON object in the following format:\n \\`\\`\\`json\n {\n \"title\": \"Generated Title\",\n \"summary\": \"Generated summary and/or description of the text\"\n }\n \\`\\`\\``;\n\n\tconst response = await runtime.useModel(ModelType.TEXT_SMALL, {\n\t\tprompt,\n\t});\n\n\tconst parsedResponse = parseJSONObjectFromText(response);\n\n\tif (parsedResponse?.title && parsedResponse?.summary) {\n\t\treturn {\n\t\t\ttitle: parsedResponse.title,\n\t\t\tdescription: parsedResponse.summary,\n\t\t};\n\t}\n\n\treturn {\n\t\ttitle: \"\",\n\t\tdescription: \"\",\n\t};\n}\n\n/**\n * Represents the content of a page.\n * @typedef { Object } PageContent\n * @property { string } title - The title of the page.\n * @property { string } description - The description of the page.\n * @property { string } bodyContent - The main content of the page.\n */\ntype PageContent = {\n\ttitle: string;\n\tdescription: string;\n\tbodyContent: string;\n};\n\n/**\n * Represents a BrowserService class that extends Service and implements IBrowserService interface.\n * Provides methods for initializing browser, stopping browser, fetching page content, solving CAPTCHAs, detecting CAPTCHAs, and getting cache key.\n * @extends Service\n * @implements IBrowserService\n */\nexport class BrowserService extends Service implements IBrowserService {\n\tprivate browser: Browser | undefined;\n\tprivate context: BrowserContext | undefined;\n\tprivate captchaSolver: CaptchaSolver;\n\tprivate cacheKey = \"content/browser\";\n\n\tstatic serviceType: ServiceTypeName = ServiceType.BROWSER;\n\tcapabilityDescription =\n\t\t\"The agent is able to browse the web and fetch content\";\n\n\t/**\n\t * Constructor for the Agent class.\n\t * @param {IAgentRuntime} runtime - The runtime object for the agent.\n\t */\n\tconstructor(runtime: IAgentRuntime) {\n\t\tsuper();\n\t\tthis.runtime = runtime;\n\t\tthis.browser = undefined;\n\t\tthis.context = undefined;\n\t\tthis.captchaSolver = new CaptchaSolver(settings.CAPSOLVER_API_KEY || \"\");\n\t}\n\n\t/**\n\t * Starts the BrowserService asynchronously.\n\t *\n\t * @param {IAgentRuntime} runtime - The runtime for the agent.\n\t * @returns {Promise<BrowserService>} A promise that resolves to the initialized BrowserService.\n\t */\n\tstatic async start(runtime: IAgentRuntime): Promise<BrowserService> {\n\t\tconst service = new BrowserService(runtime);\n\t\tawait service.initializeBrowser();\n\t\treturn service;\n\t}\n\n\t/**\n\t * Function to stop the browser service asynchronously.\n\t *\n\t * @param {IAgentRuntime} runtime - The runtime environment for the agent.\n\t */\n\tstatic async stop(runtime: IAgentRuntime) {\n\t\tconst service = runtime.getService(ServiceType.BROWSER);\n\t\tif (service) {\n\t\t\tawait service.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Initializes the browser by launching Chromium with specified options and setting the user agent based on the platform.\n\t * @returns {Promise<void>} A promise that resolves once the browser is successfully initialized.\n\t */\n\tasync initializeBrowser() {\n\t\tif (!this.browser) {\n\t\t\tthis.browser = await chromium.launch({\n\t\t\t\theadless: true,\n\t\t\t\targs: [\n\t\t\t\t\t\"--disable-dev-shm-usage\", // Uses /tmp instead of /dev/shm. Prevents memory issues on low-memory systems\n\t\t\t\t\t\"--block-new-web-contents\", // Prevents creation of new windows/tabs\n\t\t\t\t],\n\t\t\t});\n\n\t\t\tconst platform = process.platform;\n\t\t\tlet userAgent = \"\";\n\n\t\t\t// Change the user agent to match the platform to reduce bot detection\n\t\t\tswitch (platform) {\n\t\t\t\tcase \"darwin\":\n\t\t\t\t\tuserAgent =\n\t\t\t\t\t\t\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"win32\":\n\t\t\t\t\tuserAgent =\n\t\t\t\t\t\t\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"linux\":\n\t\t\t\t\tuserAgent =\n\t\t\t\t\t\t\"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\";\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tuserAgent =\n\t\t\t\t\t\t\"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\";\n\t\t\t}\n\n\t\t\tthis.context = await this.browser.newContext({\n\t\t\t\tuserAgent,\n\t\t\t\tacceptDownloads: false,\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously stops the browser and context if they are currently running.\n\t */\n\tasync stop() {\n\t\tif (this.context) {\n\t\t\tawait this.context.close();\n\t\t\tthis.context = undefined;\n\t\t}\n\t\tif (this.browser) {\n\t\t\tawait this.browser.close();\n\t\t\tthis.browser = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously fetches the content of a web page.\n\t *\n\t * @param {string} url - The URL of the web page to fetch content from.\n\t * @param {IAgentRuntime} runtime - The runtime environment for the web scraping agent.\n\t * @returns {Promise<PageContent>} A Promise that resolves with the content of the web page.\n\t */\n\tasync getPageContent(\n\t\turl: string,\n\t\truntime: IAgentRuntime,\n\t): Promise<PageContent> {\n\t\tawait this.initializeBrowser();\n\t\treturn await this.fetchPageContent(url, runtime);\n\t}\n\n\t/**\n\t * Generates a cache key for the provided URL by converting it to a UUID string.\n\t *\n\t * @param {string} url - The URL for which a cache key is being generated.\n\t * @returns {string} A UUID string representing the cache key for the URL.\n\t */\n\tprivate getCacheKey(url: string): string {\n\t\treturn stringToUuid(url);\n\t}\n\n\t/**\n\t * Fetches the content of a page from the specified URL using a headless browser.\n\t *\n\t * @param {string} url - The URL of the page to fetch the content from.\n\t * @param {IAgentRuntime} runtime - The runtime environment for the agent.\n\t * @returns {Promise<PageContent>} A promise that resolves to the content of the fetched page.\n\t */\n\tprivate async fetchPageContent(\n\t\turl: string,\n\t\truntime: IAgentRuntime,\n\t): Promise<PageContent> {\n\t\tconst cacheKey = this.getCacheKey(url);\n\t\tconst cached = await runtime\n\t\t\t\n\t\t\t.getCache<any>(`${this.cacheKey}/${cacheKey}`);\n\n\t\tif (cached) {\n\t\t\treturn cached.content;\n\t\t}\n\n\t\tlet page: Page | undefined;\n\n\t\ttry {\n\t\t\tif (!this.context) {\n\t\t\t\tlogger.log(\n\t\t\t\t\t\"Browser context not initialized. Call initializeBrowser() first.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tpage = await this.context.newPage();\n\n\t\t\t// Enable stealth mode\n\t\t\tawait page.setExtraHTTPHeaders({\n\t\t\t\t\"Accept-Language\": \"en-US,en;q=0.9\",\n\t\t\t});\n\n\t\t\tconst response = await page.goto(url, { waitUntil: \"networkidle\" });\n\n\t\t\tif (!response) {\n\t\t\t\tlogger.error(\"Failed to load the page\");\n\t\t\t}\n\n\t\t\tif (response.status() === 403 || response.status() === 404) {\n\t\t\t\treturn await this.tryAlternativeSources(url, runtime);\n\t\t\t}\n\n\t\t\t// Check for CAPTCHA\n\t\t\tconst captchaDetected = await this.detectCaptcha(page);\n\t\t\tif (captchaDetected) {\n\t\t\t\tawait this.solveCaptcha(page, url);\n\t\t\t}\n\t\t\tconst documentTitle = await page.evaluate(() => document.title);\n\t\t\tconst bodyContent = await page.evaluate(() => document.body.innerText);\n\t\t\tconst { title: parsedTitle, description } = await generateSummary(\n\t\t\t\truntime,\n\t\t\t\t`${documentTitle}\\n${bodyContent}`,\n\t\t\t);\n\t\t\tconst content = { title: parsedTitle, description, bodyContent };\n\t\t\tawait runtime\n\t\t\t\t\n\t\t\t\t.setCache<any>(`${this.cacheKey}/${cacheKey}`, {\n\t\t\t\t\turl,\n\t\t\t\t\tcontent,\n\t\t\t\t});\n\t\t\treturn content;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Error:\", error);\n\t\t\treturn {\n\t\t\t\ttitle: url,\n\t\t\t\tdescription: \"Error, could not fetch content\",\n\t\t\t\tbodyContent: \"\",\n\t\t\t};\n\t\t} finally {\n\t\t\tif (page) {\n\t\t\t\tawait page.close();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Detects if a captcha is present on the page based on the specified selectors.\n\t *\n\t * @param {Page} page The Puppeteer page to check for captcha.\n\t * @returns {Promise<boolean>} A boolean indicating whether a captcha was detected.\n\t */\n\tprivate async detectCaptcha(page: Page): Promise<boolean> {\n\t\tconst captchaSelectors = [\n\t\t\t'iframe[src*=\"captcha\"]',\n\t\t\t'div[class*=\"captcha\"]',\n\t\t\t\"#captcha\",\n\t\t\t\".g-recaptcha\",\n\t\t\t\".h-captcha\",\n\t\t];\n\n\t\tfor (const selector of captchaSelectors) {\n\t\t\tconst element = await page.$(selector);\n\t\t\tif (element) return true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Solves the CAPTCHA challenge on the provided page using either hCaptcha or reCaptcha.\n\t *\n\t * @param {Page} page - The page where the CAPTCHA challenge needs to be solved.\n\t * @param {string} url - The URL of the website with the CAPTCHA challenge.\n\t * @returns {Promise<void>} - A promise that resolves once the CAPTCHA is solved.\n\t */\n\tprivate async solveCaptcha(page: Page, url: string): Promise<void> {\n\t\ttry {\n\t\t\tconst hcaptchaKey = await this.getHCaptchaWebsiteKey(page);\n\t\t\tif (hcaptchaKey) {\n\t\t\t\tconst solution = await this.captchaSolver.hcaptchaProxyless({\n\t\t\t\t\twebsiteURL: url,\n\t\t\t\t\twebsiteKey: hcaptchaKey,\n\t\t\t\t});\n\t\t\t\tawait page.evaluate((token) => {\n\t\t\t\t\t// eslint-disable-next-line\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\twindow.hcaptcha.setResponse(token);\n\t\t\t\t}, solution.gRecaptchaResponse);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst recaptchaKey = await this.getReCaptchaWebsiteKey(page);\n\t\t\tif (recaptchaKey) {\n\t\t\t\tconst solution = await this.captchaSolver.recaptchaV2Proxyless({\n\t\t\t\t\twebsiteURL: url,\n\t\t\t\t\twebsiteKey: recaptchaKey,\n\t\t\t\t});\n\t\t\t\tawait page.evaluate((token) => {\n\t\t\t\t\t// eslint-disable-next-line\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tdocument.getElementById(\"g-recaptcha-response\").innerHTML = token;\n\t\t\t\t}, solution.gRecaptchaResponse);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Error solving CAPTCHA:\", error);\n\t\t}\n\t}\n\n\t/**\n\t * Get the hCaptcha website key from the given Page\n\t * @param {Page} page - The Page object to extract the hCaptcha website key from\n\t * @returns {Promise<string>} The hCaptcha website key\n\t */\n\tprivate async getHCaptchaWebsiteKey(page: Page): Promise<string> {\n\t\treturn page.evaluate(() => {\n\t\t\tconst hcaptchaIframe = document.querySelector(\n\t\t\t\t'iframe[src*=\"hcaptcha.com\"]',\n\t\t\t);\n\t\t\tif (hcaptchaIframe) {\n\t\t\t\tconst src = hcaptchaIframe.getAttribute(\"src\");\n\t\t\t\tconst match = src?.match(/sitekey=([^&]*)/);\n\t\t\t\treturn match ? match[1] : \"\";\n\t\t\t}\n\t\t\treturn \"\";\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves the ReCaptcha website key from a given page.\n\t * @param {Page} page - The page to extract the ReCaptcha website key from.\n\t * @returns {Promise<string>} The ReCaptcha website key, or an empty string if not found.\n\t */\n\tprivate async getReCaptchaWebsiteKey(page: Page): Promise<string> {\n\t\treturn page.evaluate(() => {\n\t\t\tconst recaptchaElement = document.querySelector(\".g-recaptcha\");\n\t\t\treturn recaptchaElement\n\t\t\t\t? recaptchaElement.getAttribute(\"data-sitekey\") || \"\"\n\t\t\t\t: \"\";\n\t\t});\n\t}\n\n\t/**\n\t * Try fetching content from alternative sources if the original source fails.\n\t *\n\t * @param {string} url - The URL of the content to fetch.\n\t * @param {IAgentRuntime} runtime - The runtime environment.\n\t * @returns {Promise<{ title: string; description: string; bodyContent: string }>} The fetched content with title, description, and body.\n\t */\n\tprivate async tryAlternativeSources(\n\t\turl: string,\n\t\truntime: IAgentRuntime,\n\t): Promise<{ title: string; description: string; bodyContent: string }> {\n\t\t// because this (tryAlternativeSources) calls fetchPageContent\n\t\t// and fetchPageContent calls tryAlternativeSources\n\t\t// we need these url.matches to progress\n\t\t// through the things to try\n\t\tif (!url.match(/web.archive.org\\/web/)) {\n\t\t\t// Try Internet Archive\n\t\t\tconst archiveUrl = `https://web.archive.org/web/${url}`;\n\t\t\ttry {\n\t\t\t\treturn await this.fetchPageContent(archiveUrl, runtime);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Error fetching from Internet Archive:\", error);\n\t\t\t}\n\t\t}\n\n\t\tif (!url.match(/www.google.com\\/search/)) {\n\t\t\t// Try Google Search as a last resort\n\t\t\tconst googleSearchUrl = `https://www.google.com/search?q=${encodeURIComponent(\n\t\t\t\turl,\n\t\t\t)}`;\n\t\t\ttry {\n\t\t\t\treturn await this.fetchPageContent(googleSearchUrl, runtime);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Error fetching from Google Search:\", error);\n\t\t\t\tlogger.error(\"Failed to fetch content from alternative sources\");\n\t\t\t\treturn {\n\t\t\t\t\ttitle: url,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Error, could not fetch content from alternative sources\",\n\t\t\t\t\tbodyContent: \"\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n}\n","import {\n\ttype IAgentRuntime,\n\ttype IPdfService,\n\tService,\n\ttype ServiceTypeName,\n\tServiceType,\n} from \"@elizaos/core\";\nimport { type PDFDocumentProxy, getDocument } from \"pdfjs-dist\";\nimport type {\n\tTextItem,\n\tTextMarkedContent,\n} from \"pdfjs-dist/types/src/display/api\";\n\n/**\n * Class representing a PDF service that can convert PDF files to text.\n * * @extends Service\n * @implements IPdfService\n */\nexport class PdfService extends Service implements IPdfService {\n\tstatic serviceType: ServiceTypeName = ServiceType.PDF;\n\tcapabilityDescription = \"The agent is able to convert PDF files to text\";\n\n\t/**\n\t * Constructor for creating a new instance of the class.\n\t *\n\t * @param {IAgentRuntime} runtime - The runtime object passed to the constructor.\n\t */\n\tconstructor(runtime: IAgentRuntime) {\n\t\tsuper();\n\t\tthis.runtime = runtime;\n\t}\n\n\t/**\n\t * Starts the PdfService asynchronously.\n\t * @param {IAgentRuntime} runtime - The runtime object for the agent.\n\t * @returns {Promise<PdfService>} A promise that resolves with the PdfService instance.\n\t */\n\tstatic async start(runtime: IAgentRuntime): Promise<PdfService> {\n\t\tconst service = new PdfService(runtime);\n\t\treturn service;\n\t}\n\n\t/**\n\t * Stop the PDF service in the given runtime.\n\t *\n\t * @param {IAgentRuntime} runtime - The runtime to stop the PDF service in.\n\t * @returns {Promise<void>} - A promise that resolves once the PDF service is stopped.\n\t */\n\tstatic async stop(runtime: IAgentRuntime) {\n\t\tconst service = runtime.getService(ServiceType.PDF);\n\t\tif (service) {\n\t\t\tawait service.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously stops the process.\n\t * Does nothing.\n\t */\n\tasync stop() {\n\t\t// do nothing\n\t}\n\n\t/**\n\t * Converts a PDF Buffer to text.\n\t *\n\t * @param {Buffer} pdfBuffer - The PDF Buffer to convert to text.\n\t * @returns {Promise<string>} A Promise that resolves with the text content of the PDF.\n\t */\n\tasync convertPdfToText(pdfBuffer: Buffer): Promise<string> {\n\t\t// Convert Buffer to Uint8Array\n\t\tconst uint8Array = new Uint8Array(pdfBuffer);\n\n\t\tconst pdf: PDFDocumentProxy = await getDocument({ data: uint8Array })\n\t\t\t.promise;\n\t\tconst numPages = pdf.numPages;\n\t\tconst textPages: string[] = [];\n\n\t\tfor (let pageNum = 1; pageNum <= numPages; pageNum++) {\n\t\t\tconst page = await pdf.getPage(pageNum);\n\t\t\tconst textContent = await page.getTextContent();\n\t\t\tconst pageText = textContent.items\n\t\t\t\t.filter(isTextItem)\n\t\t\t\t.map((item) => item.str)\n\t\t\t\t.join(\" \");\n\t\t\ttextPages.push(pageText);\n\t\t}\n\n\t\treturn textPages.join(\"\\n\");\n\t}\n}\n\n// Type guard function\n/**\n * Check if the input is a TextItem.\n *\n * @param item - The input item to check.\n * @returns A boolean indicating if the input is a TextItem.\n */\nfunction isTextItem(item: TextItem | TextMarkedContent): item is TextItem {\n\treturn \"str\" in item;\n}\n","import fs from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport {\n\ttype IAgentRuntime,\n\ttype IVideoService,\n\ttype Media,\n\tModelType,\n\tService,\n\ttype ServiceTypeName,\n\tServiceType,\n\tlogger,\n\tstringToUuid,\n} from \"@elizaos/core\";\nimport ffmpeg from \"fluent-ffmpeg\";\nimport ytdl, { create } from \"youtube-dl-exec\";\n\n/**\n * Function to get the Youtube DL executable path.\n * It first checks if /usr/local/bin/yt-dlp exists,\n * if it does, it returns the path to that executable.\n * If not, it checks if /usr/bin/yt-dlp exists,\n * and returns the path if found.\n * If neither paths exist, it returns the default ytdl executable.\n * @returns {string} The path to the Youtube DL executable.\n */\nfunction getYoutubeDL() {\n\t// first check if /usr/local/bin/yt-dlp exists\n\tif (fs.existsSync(\"/usr/local/bin/yt-dlp\")) {\n\t\treturn create(\"/usr/local/bin/yt-dlp\");\n\t}\n\n\t// if not, check if /usr/bin/yt-dlp exists\n\tif (fs.existsSync(\"/usr/bin/yt-dlp\")) {\n\t\treturn create(\"/usr/bin/yt-dlp\");\n\t}\n\n\t// use default otherwise\n\treturn ytdl;\n}\n\n/**\n * VideoService class that extends Service and implements IVideoService interface.\n * Defines the service type as VIDEO and sets capability description for processing videos.\n * Manages caching of video content with cacheKey and dataDir properties.\n * Maintains a queue of video processing tasks and tracks processing status.\n */\nexport class VideoService extends Service implements IVideoService {\n\tstatic serviceType: ServiceTypeName = ServiceType.VIDEO;\n\tcapabilityDescription = \"The agent is able to download and process videos\";\n\tprivate cacheKey = \"content/video\";\n\tprivate dataDir = \"./cache\";\n\n\tprivate queue: string[] = [];\n\tprivate processing = false;\n\n\t/**\n\t * Constructor for creating a new instance of the object.\n\t *\n\t * @param {IAgentRuntime} runtime - The runtime object to be used by the instance\n\t */\n\tconstructor(runtime: IAgentRuntime) {\n\t\tsuper();\n\t\tthis.runtime = runtime;\n\t\tthis.ensureDataDirectoryExists();\n\t}\n\n\t/**\n\t * Starts the VideoService by initializing it with the given IAgentRuntime instance.\n\t *\n\t * @param {IAgentRuntime} runtime - The IAgentRuntime instance to initialize the service with.\n\t * @returns {Promise<VideoService>} A promise that resolves to the initialized VideoService instance.\n\t */\n\tstatic async start(runtime: IAgentRuntime): Promise<VideoService> {\n\t\tconst service = new VideoService(runtime);\n\t\treturn service;\n\t}\n\n\t/**\n\t * Stops the video service if it is running.\n\t *\n\t * @param {IAgentRuntime} runtime - The agent runtime instance\n\t * @returns {Promise<void>} A promise that resolves once the video service is stopped\n\t */\n\tstatic async stop(runtime: IAgentRuntime) {\n\t\tconst service = runtime.getService(ServiceType.VIDEO);\n\t\tif (service) {\n\t\t\tawait service.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronous method to stop the operation.\n\t */\n\tasync stop() {\n\t\t// do nothing\n\t}\n\n\t/**\n\t * Checks if the data directory exists, and if not, creates it.\n\t */\n\tprivate ensureDataDirectoryExists() {\n\t\tif (!fs.existsSync(this.dataDir)) {\n\t\t\tfs.mkdirSync(this.dataDir);\n\t\t}\n\t}\n\n\t/**\n\t * Check if a given URL is a video URL from YouTube or Vimeo.\n\t *\n\t * @param {string} url - The URL to check.\n\t * @return {boolean} Returns true if the URL is from YouTube or Vimeo, false otherwise.\n\t */\n\tpublic isVideoUrl(url: string): boolean {\n\t\treturn (\n\t\t\turl.includes(\"youtube.com\") ||\n\t\t\turl.includes(\"youtu.be\") ||\n\t\t\turl.includes(\"vimeo.com\")\n\t\t);\n\t}\n\n\t/**\n\t * Downloads media from a given URL. If the media already exists, it returns the file path.\n\t *\n\t * @param {string} url - The URL of the media to download.\n\t * @returns {Promise<string>} A promise that resolves to the file path of the downloaded media.\n\t * @throws {Error} If there is an error downloading the media.\n\t */\n\tpublic async downloadMedia(url: string): Promise<string> {\n\t\tconst videoId = this.getVideoId(url);\n\t\tconst outputFile = path.join(this.dataDir, `${videoId}.mp4`);\n\n\t\t// if it already exists, return it\n\t\tif (fs.existsSync(outputFile)) {\n\t\t\treturn outputFile;\n\t\t}\n\n\t\ttry {\n\t\t\tawait getYoutubeDL()(url, {\n\t\t\t\tverbose: true,\n\t\t\t\toutput: outputFile,\n\t\t\t\twriteInfoJson: true,\n\t\t\t});\n\t\t\treturn outputFile;\n\t\t} catch (error) {\n\t\t\tlogger.log(\"Error downloading media:\", error);\n\t\t\tthrow new Error(\"Failed to download media\");\n\t\t}\n\t}\n\n\t/**\n\t * Downloads a video using the videoInfo object provided and returns the path to the downloaded video file.\n\t * If the video file already exists, it will return the path without re-downloading.\n\t * @param {Object} videoInfo - Information about the video to download.\n\t * @returns {Promise<string>} - Path to the downloaded video file.\n\t */\n\tpublic async downloadVideo(videoInfo: any): Promise<string> {\n\t\tconst videoId = this.getVideoId(videoInfo.webpage_url);\n\t\tconst outputFile = path.join(this.dataDir, `${videoId}.mp4`);\n\n\t\t// if it already exists, return it\n\t\tif (fs.existsSync(outputFile)) {\n\t\t\treturn outputFile;\n\t\t}\n\n\t\ttry {\n\t\t\tawait getYoutubeDL()(videoInfo.webpage_url, {\n\t\t\t\tverbose: true,\n\t\t\t\toutput: outputFile,\n\t\t\t\tformat: \"bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best\",\n\t\t\t\twriteInfoJson: true,\n\t\t\t});\n\t\t\treturn outputFile;\n\t\t} catch (error) {\n\t\t\tlogger.log(\"Error downloading video:\", error);\n\t\t\tthrow new Error(\"Failed to download video\");\n\t\t}\n\t}\n\n\t/**\n\t * Process a video from the given URL using the provided agent runtime.\n\t *\n\t * @param {string} url - The URL of the video to be processed\n\t * @param {IAgentRuntime} runtime - The agent runtime to be used for processing the video\n\t * @returns {Promise<Media>} A promise that resolves to the processed media\n\t */\n\tpublic async processVideo(\n\t\turl: string,\n\t\truntime: IAgentRuntime,\n\t): Promise<Media> {\n\t\tthis.queue.push(url);\n\t\tawait this.processQueue(runtime);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst checkQueue = async () => {\n\t\t\t\tconst index = this.queue.indexOf(url);\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\tsetTimeout(checkQueue, 100);\n\t\t\t\t} else {\n\t\t\t\t\tthis.processVideoFromUrl(url, runtime).then(resolve).catch(reject);\n\t\t\t\t}\n\t\t\t};\n\t\t\tcheckQueue();\n\t\t});\n\t}\n\n\t/**\n\t * Processes the queue of URLs by calling processVideoFromUrl for each URL.\n\t *\n\t * @param {any} runtime - The runtime information for processing the videos.\n\t * @returns {Promise<void>} - A promise that resolves when the queue has been processed.\n\t */\n\tprivate async processQueue(runtime): Promise<void> {\n\t\tif (this.processing || this.queue.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.processing = true;\n\n\t\twhile (this.queue.length > 0) {\n\t\t\tconst url = this.queue.shift()!;\n\t\t\tawait this.processVideoFromUrl(url, runtime);\n\t\t}\n\n\t\tthis.processing = false;\n\t}\n\n\t/**\n\t * Processes a video from a given URL.\n\t * Retrieves video information, transcript, and caches the result.\n\t *\n\t * @param {string} url - The URL of the video to process.\n\t * @param {IAgentRuntime} runtime - The runtime environment for the agent.\n\t * @returns {Promise<Media>} A promise that resolves to the processed video data.\n\t * @throws {Error} If there is an error processing the video.\n\t */\n\tprivate async processVideoFromUrl(\n\t\turl: string,\n\t\truntime: IAgentRuntime,\n\t): Promise<Media> {\n\t\tconst videoId =\n\t\t\turl.match(\n\t\t\t\t/(?:youtu\\.be\\/|youtube\\.com(?:\\/embed\\/|\\/v\\/|\\/watch\\?v=|\\/watch\\?.+&v=))([^\\/&?]+)/, // eslint-disable-line\n\t\t\t)?.[1] || \"\";\n\t\tconst videoUuid = this.getVideoId(videoId);\n\t\tconst cacheKey = `${this.cacheKey}/${videoUuid}`;\n\n\t\tconst cached = await runtime.getCache<Media>(cacheKey);\n\n\t\tif (cached) {\n\t\t\tlogger.log(\"Returning cached video file\");\n\t\t\treturn cached;\n\t\t}\n\n\t\ttry {\n\t\t\tlogger.log(\"Cache miss, processing video\");\n\t\t\tlogger.log(\"Fetching video info\");\n\t\t\tconst videoInfo = await this.fetchVideoInfo(url);\n\t\t\tconsole.log(\"Getting transcript\");\n\t\t\tconst transcript = await this.getTranscript(url, videoInfo, runtime);\n\n\t\t\tconst result: Media = {\n\t\t\t\tid: videoUuid,\n\t\t\t\turl: url,\n\t\t\t\ttitle: videoInfo.title,\n\t\t\t\tsource: videoInfo.channel,\n\t\t\t\tdescription: videoInfo.description,\n\t\t\t\ttext: transcript,\n\t\t\t};\n\n\t\t\tawait runtime.setCache<Media>(cacheKey, result);\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Error processing video: ${error.message || error}`);\n\t\t}\n\t}\n\n\t/**\n\t * Returns the unique video ID generated from the provided URL.\n\t * @param {string} url - The URL used to generate the video ID.\n\t * @returns {string} The unique video ID.\n\t */\n\tprivate getVideoId(url: string): string {\n\t\treturn stringToUuid(url);\n\t}\n\n\t/**\n\t * Asynchronously fetches video information from the provided URL. If the URL ends with \".mp4\" or includes \".mp4?\", attempts to fetch the video directly using fetch. If successful, returns a simplified video info object with title, description, and channel. If direct download fails, falls back to using youtube-dl to fetch video information. Utilizes options such as dumpJson, verbose, callHome, noCheckCertificates, preferFreeFormats, youtubeSkipDashManifest, writeSub, writeAutoSub, subLang, and skipDownload when calling youtube-dl. Throws an error if the response from youtube-dl is empty or if there is an error during the process.\n\t *\n\t * @param {string} url - The URL from which to fetch video information\n\t * @returns {Promise<any>} A Promise resolving to the fetched video information or rejecting with an error message\n\t */\n\tasync fetchVideoInfo(url: string): Promise<any> {\n\t\tconsole.log(\"url\", url);\n\t\tif (url.endsWith(\".mp4\") || url.includes(\".mp4?\")) {\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(url);\n\t\t\t\tif (response.ok) {\n\t\t\t\t\t// If the URL is a direct link to an MP4 file, return a simplified video info object\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttitle: path.basename(url),\n\t\t\t\t\t\tdescription: \"\",\n\t\t\t\t\t\tchannel: \"\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlogger.log(\"Error downloading MP4 file:\", error);\n\t\t\t\t// Fall back to using youtube-dl if direct download fails\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await getYoutubeDL()(url, {\n\t\t\t\tdumpJson: true,\n\t\t\t\tverbose: true,\n\t\t\t\tcallHome: false,\n\t\t\t\tnoCheckCertificates: true,\n\t\t\t\tpreferFreeFormats: true,\n\t\t\t\tyoutubeSkipDashManifest: true,\n\t\t\t\twriteSub: true,\n\t\t\t\twriteAutoSub: true,\n\t\t\t\tsubLang: \"en\",\n\t\t\t\tskipDownload: true,\n\t\t\t});\n\n\t\t\tif (!result || Object.keys(result).length === 0) {\n\t\t\t\tthrow new Error(\"Empty response from youtube-dl\");\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to fetch video information: ${error.message || error}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously retrieves the transcript of a video based on the provided URL, video information, and runtime environment.\n\t *\n\t * @param {string} url - The URL of the video.\n\t * @param {any} videoInfo - Information about the video, including subtitles, automatic captions, and categories.\n\t * @param {IAgentRuntime} runtime - The runtime environment of the agent.\n\t * @returns {Promise<string>} A Promise that resolves to the transcript of the video.\n\t */\n\tprivate async getTranscript(\n\t\turl: string,\n\t\tvideoInfo: any,\n\t\truntime: IAgentRuntime,\n\t): Promise<string> {\n\t\tlogger.log(\"Getting transcript\");\n\t\ttry {\n\t\t\t// Check for manual subtitles\n\t\t\tif (videoInfo.subtitles?.en) {\n\t\t\t\tlogger.log(\"Manual subtitles found\");\n\t\t\t\tconst srtContent = await this.downloadSRT(\n\t\t\t\t\tvideoInfo.subtitles.en[0].url,\n\t\t\t\t);\n\t\t\t\treturn this.parseSRT(srtContent);\n\t\t\t}\n\n\t\t\t// Check for automatic captions\n\t\t\tif (videoInfo.automatic_captions?.en) {\n\t\t\t\tlogger.log(\"Automatic captions found\");\n\t\t\t\tconst captionUrl = videoInfo.automatic_captions.en[0].url;\n\t\t\t\tconst captionContent = await this.downloadCaption(captionUrl);\n\t\t\t\treturn this.parseCaption(captionContent);\n\t\t\t}\n\n\t\t\t// Check if it's a music video\n\t\t\tif (videoInfo.categories?.includes(\"Music\")) {\n\t\t\t\tlogger.log(\"Music video detected, no lyrics available\");\n\t\t\t\treturn \"No lyrics available.\";\n\t\t\t}\n\n\t\t\t// Fall back to audio transcription\n\t\t\tlogger.log(\n\t\t\t\t\"No subtitles or captions found, falling back to audio transcription\",\n\t\t\t);\n\t\t\treturn this.transcribeAudio(url, runtime);\n\t\t} catch (error) {\n\t\t\tlogger.log(\"Error in getTranscript:\", error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Downloads a caption from the specified URL.\n\t * @param {string} url - The URL from which to download the caption.\n\t * @returns {Promise<string>} A promise that resolves with the downloaded caption as a string.\n\t * @throws {Error} If the caption download fails, an error is thrown with the reason.\n\t */\n\tprivate async downloadCaption(url: string): Promise<string> {\n\t\tlogger.log(\"Downloading caption from:\", url);\n\t\tconst response = await fetch(url);\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to download caption: ${response.statusText}`);\n\t\t}\n\t\treturn await response.text();\n\t}\n\n\t/**\n\t * Parses the given caption content to extract relevant information.\n\t *\n\t * @param {string} captionContent - The caption content to parse.\n\t * @returns {string} The extracted caption information as a string.\n\t */\n\tprivate parseCaption(captionContent: string): string {\n\t\tlogger.log(\"Parsing caption\");\n\t\ttry {\n\t\t\tconst jsonContent = JSON.parse(captionContent);\n\t\t\tif (jsonContent.events) {\n\t\t\t\treturn jsonContent.events\n\t\t\t\t\t.filter((event) => event.segs)\n\t\t\t\t\t.map((event) => event.segs.map((seg) => seg.utf8).join(\"\"))\n\t\t\t\t\t.join(\"\")\n\t\t\t\t\t.replace(\"\\n\", \" \");\n\t\t\t}\n\t\t\tlogger.log(\"Unexpected caption format:\", jsonContent);\n\t\t\treturn \"Error: Unable to parse captions\";\n\t\t} catch (error) {\n\t\t\tlogger.log(\"Error parsing caption:\", error);\n\t\t\treturn \"Error: Unable to parse captions\";\n\t\t}\n\t}\n\n\t/**\n\t * Parses SRT (SubRip) content to extract subtitles.\n\t *\n\t * @param {string} srtContent - The SRT content to parse.\n\t * @returns {string} The parsed subtitles as a single string.\n\t */\n\tprivate parseSRT(srtContent: string): string {\n\t\t// Simple SRT parser (replace with a more robust solution if needed)\n\t\treturn srtContent\n\t\t\t.split(\"\\n\\n\")\n\t\t\t.map((block) => block.split(\"\\n\").slice(2).join(\" \"))\n\t\t\t.join(\" \");\n\t}\n\n\t/**\n\t * Asynchronously downloads a SubRip subtitle file from the specified URL.\n\t *\n\t * @param {string} url - The URL of the subtitle file to download.\n\t * @returns {Promise<string>} A promise that resolves to the text content of the downloaded subtitle file.\n\t */\n\tprivate async downloadSRT(url: string): Promise<string> {\n\t\tlogger.log(\"downloadSRT\");\n\t\tconst response = await fetch(url);\n\t\treturn await response.text();\n\t}\n\n\t/**\n\t * Asynchronously transcribes audio from the provided URL using the agent runtime.\n\t *\n\t * @param {string} url - The URL of the audio file to transcribe.\n\t * @param {IAgentRuntime} runtime - The agent runtime to use for transcription.\n\t * @returns {Promise<string>} A promise that resolves with the transcription result, or \"Transcription failed\" if the process was unsuccessful.\n\t */\n\tasync transcribeAudio(url: string, runtime: IAgentRuntime): Promise<string> {\n\t\tlogger.log(\"Preparing audio for transcription...\");\n\n\t\t// Check if ffmpeg exists in PATH\n\t\ttry {\n\t\t\tawait new Promise((resolve, reject) => {\n\t\t\t\tffmpeg.getAvailableCodecs((err, _codecs) => {\n\t\t\t\t\tif (err) reject(err);\n\t\t\t\t\tresolve(null);\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlogger.log(\"FFmpeg not found:\", error);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst mp4FilePath = path.join(this.dataDir, `${this.getVideoId(url)}.mp4`);\n\n\t\tconst webmFilePath = path.join(\n\t\t\tthis.dataDir,\n\t\t\t`${this.getVideoId(url)}.webm`,\n\t\t);\n\n\t\tconst mp3FilePath = path.join(this.dataDir, `${this.getVideoId(url)}.mp3`);\n\n\t\tif (!fs.existsSync(mp3FilePath)) {\n\t\t\tif (fs.existsSync(webmFilePath)) {\n\t\t\t\tlogger.log(\"WEBM file found. Converting to MP3...\");\n\t\t\t\tawait this.convertWebmToMp3(webmFilePath, mp3FilePath);\n\t\t\t} else if (fs.existsSync(mp4FilePath)) {\n\t\t\t\tlogger.log(\"MP4 file found. Converting to MP3...\");\n\t\t\t\tawait this.convertMp4ToMp3(mp4FilePath, mp3FilePath);\n\t\t\t} else {\n\t\t\t\tlogger.log(\"Downloading audio...\");\n\t\t\t\tawait this.downloadAudio(url, mp3FilePath);\n\t\t\t}\n\t\t}\n\n\t\tlogger.log(`Audio prepared at ${mp3FilePath}`);\n\n\t\tconst audioBuffer = fs.readFileSync(mp3FilePath);\n\t\tlogger.log(`Audio file size: ${audioBuffer.length} bytes`);\n\n\t\tlogger.log(\"Starting transcription...\");\n\t\tconst startTime = Date.now();\n\t\tconst transcript = await runtime.useModel(\n\t\t\tModelType.TRANSCRIPTION,\n\t\t\taudioBuffer,\n\t\t);\n\n\t\tconst endTime = Date.now();\n\t\tlogger.log(\n\t\t\t`Transcription completed in ${(endTime - startTime) / 1000} seconds`,\n\t\t);\n\n\t\t// Don't delete the MP3 file as it might be needed for future use\n\t\treturn transcript || \"Transcription failed\";\n\t}\n\n\t/**\n\t * Converts a given MP4 file to MP3 format.\n\t *\n\t * @param {string} inputPath - The path to the input MP4 file.\n\t * @param {string} outputPath - The desired path for the output MP3 file.\n\t * @returns {Promise<void>} A Promise that resolves once the conversion is complete or rejects with an error.\n\t */\n\tprivate async convertMp4ToMp3(\n\t\tinputPath: string,\n\t\toutputPath: string,\n\t): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tffmpeg(inputPath)\n\t\t\t\t.output(outputPath)\n\t\t\t\t.noVideo()\n\t\t\t\t.audioCodec(\"libmp3lame\")\n\t\t\t\t.on(\"end\", () => {\n\t\t\t\t\tlogger.log(\"Conversion to MP3 complete\");\n\t\t\t\t\tresolve();\n\t\t\t\t})\n\t\t\t\t.on(\"error\", (err) => {\n\t\t\t\t\tlogger.log(\"Error converting to MP3:\", err);\n\t\t\t\t\treject(err);\n\t\t\t\t})\n\t\t\t\t.run();\n\t\t});\n\t}\n\n\t/**\n\t * Convert a WebM file to MP3 format.\n\t *\n\t * @param {string} inputPath - The path of the WebM file to convert.\n\t * @param {string} outputPath - The path where the MP3 file will be saved.\n\t * @returns {Promise<void>} Promise that resolves when the conversion is complete.\n\t */\n\tprivate async convertWebmToMp3(\n\t\tinputPath: string,\n\t\toutputPath: string,\n\t): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tffmpeg(inputPath)\n\t\t\t\t.output(outputPath)\n\t\t\t\t.noVideo()\n\t\t\t\t.audioCodec(\"libmp3lame\")\n\t\t\t\t.on(\"end\", () => {\n\t\t\t\t\tlogger.log(\"Conversion to MP3 complete\");\n\t\t\t\t\tresolve();\n\t\t\t\t})\n\t\t\t\t.on(\"error\", (err) => {\n\t\t\t\t\tlogger.log(\"Error converting to MP3:\", err);\n\t\t\t\t\treject(err);\n\t\t\t\t})\n\t\t\t\t.run();\n\t\t});\n\t}\n\n\t/**\n\t * Downloads audio from a given URL and saves it to the specified output file.\n\t * If no output file is provided, it will default to saving the audio in the data directory with the video ID as the filename.\n\t * Supports downloading and converting MP4 files to MP3 as well as downloading audio from YouTube videos using youtube-dl.\n\t *\n\t * @param url - The URL of the audio to download.\n\t * @param outputFile - The path to save the downloaded audio file. If not provided, it defaults to saving in the data directory with the video ID as the filename.\n\t * @returns A Promise that resolves with the path to the downloaded audio file.\n\t * @throws Error if there is an issue during the download process.\n\t */\n\tprivate async downloadAudio(\n\t\turl: string,\n\t\toutputFile: string,\n\t): Promise<string> {\n\t\tlogger.log(\"Downloading audio\");\n\t\toutputFile =\n\t\t\toutputFile ?? path.join(this.dataDir, `${this.getVideoId(url)}.mp3`);\n\n\t\ttry {\n\t\t\tif (url.endsWith(\".mp4\") || url.includes(\".mp4?\")) {\n\t\t\t\tlogger.log(\n\t\t\t\t\t\"Direct MP4 file detected, downloading and converting to MP3\",\n\t\t\t\t);\n\t\t\t\tconst tempMp4File = path.join(tmpdir(), `${this.getVideoId(url)}.mp4`);\n\t\t\t\tconst response = await fetch(url);\n\t\t\t\tconst arrayBuffer = await response.arrayBuffer();\n\t\t\t\tconst buffer = Buffer.from(arrayBuffer);\n\t\t\t\tfs.writeFileSync(tempMp4File, buffer);\n\n\t\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\t\tffmpeg(tempMp4File)\n\t\t\t\t\t\t.output(outputFile)\n\t\t\t\t\t\t.noVideo()\n\t\t\t\t\t\t.audioCodec(\"libmp3lame\")\n\t\t\t\t\t\t.on(\"end\", () => {\n\t\t\t\t\t\t\tfs.unlinkSync(tempMp4File);\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.on(\"error\", (err) => {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.run();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tlogger.log(\"YouTube video detected, downloading audio with youtube-dl\");\n\t\t\t\tawait getYoutubeDL()(url, {\n\t\t\t\t\tverbose: true,\n\t\t\t\t\textractAudio: true,\n\t\t\t\t\taudioFormat: \"mp3\",\n\t\t\t\t\toutput: outputFile,\n\t\t\t\t\twriteInfoJson: true,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn outputFile;\n\t\t} catch (error) {\n\t\t\tlogger.log(\"Error downloading audio:\", error);\n\t\t\tthrow new Error(\"Failed to download audio\");\n\t\t}\n\t}\n}\n","export * from \"./services/index\";\n\nimport type { Plugin } from \"@elizaos/core\";\n\nimport {\n\tAwsS3Service,\n\tBrowserService,\n\tPdfService,\n\tVideoService,\n} from \"./services/index\";\n\nexport const nodePlugin: Plugin = {\n\tname: \"default\",\n\tdescription: \"Default plugin, with basic actions and evaluators\",\n\tservices: [BrowserService, PdfService, VideoService, AwsS3Service],\n\tactions: [],\n};\n"],"mappings":"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","names":["path","require_src","create","args","Service","ServiceType","logger","Service","ServiceType","fs","path","ModelType","Service","ServiceType","logger","stringToUuid","ytdl"]}
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/dargs/index.js","../../../node_modules/tinyspawn/src/index.js","../../../node_modules/is-unix/index.js","../../../node_modules/youtube-dl-exec/src/constants.js","../../../node_modules/youtube-dl-exec/src/index.js","../src/services/awsS3.ts","../src/services/browser.ts","../src/services/pdf.ts","../src/services/video.ts","../src/index.ts"],"sourcesContent":["'use strict';\n\nconst match = (array, value) =>\n\tarray.some(x => (x instanceof RegExp ? x.test(value) : x === value));\n\nconst dargs = (object, options) => {\n\tconst arguments_ = [];\n\tlet extraArguments = [];\n\tlet separatedArguments = [];\n\n\toptions = {\n\t\tuseEquals: true,\n\t\tshortFlag: true,\n\t\t...options\n\t};\n\n\tconst makeArguments = (key, value) => {\n\t\tconst prefix = options.shortFlag && key.length === 1 ? '-' : '--';\n\t\tconst theKey = (options.allowCamelCase ?\n\t\t\tkey :\n\t\t\tkey.replace(/[A-Z]/g, '-$&').toLowerCase());\n\n\t\tkey = prefix + theKey;\n\n\t\tif (options.useEquals) {\n\t\t\targuments_.push(key + (value ? `=${value}` : ''));\n\t\t} else {\n\t\t\targuments_.push(key);\n\n\t\t\tif (value) {\n\t\t\t\targuments_.push(value);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst makeAliasArg = (key, value) => {\n\t\targuments_.push(`-${key}`);\n\n\t\tif (value) {\n\t\t\targuments_.push(value);\n\t\t}\n\t};\n\n\tfor (let [key, value] of Object.entries(object)) {\n\t\tlet pushArguments = makeArguments;\n\n\t\tif (Array.isArray(options.excludes) && match(options.excludes, key)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(options.includes) && !match(options.includes, key)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (typeof options.aliases === 'object' && options.aliases[key]) {\n\t\t\tkey = options.aliases[key];\n\t\t\tpushArguments = makeAliasArg;\n\t\t}\n\n\t\tif (key === '--') {\n\t\t\tif (!Array.isArray(value)) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`Expected key \\`--\\` to be Array, got ${typeof value}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tseparatedArguments = value;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (key === '_') {\n\t\t\tif (!Array.isArray(value)) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`Expected key \\`_\\` to be Array, got ${typeof value}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\textraArguments = value;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (value === true) {\n\t\t\tpushArguments(key, '');\n\t\t}\n\n\t\tif (value === false && !options.ignoreFalse) {\n\t\t\tpushArguments(`no-${key}`);\n\t\t}\n\n\t\tif (typeof value === 'string') {\n\t\t\tpushArguments(key, value);\n\t\t}\n\n\t\tif (typeof value === 'number' && !Number.isNaN(value)) {\n\t\t\tpushArguments(key, String(value));\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const arrayValue of value) {\n\t\t\t\tpushArguments(key, arrayValue);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const argument of extraArguments) {\n\t\targuments_.push(String(argument));\n\t}\n\n\tif (separatedArguments.length > 0) {\n\t\targuments_.push('--');\n\t}\n\n\tfor (const argument of separatedArguments) {\n\t\targuments_.push(String(argument));\n\t}\n\n\treturn arguments_;\n};\n\nmodule.exports = dargs;\n","'use strict'\n\nconst { spawn } = require('child_process')\nconst { EOL } = require('os')\n\nconst EE_PROPS = Object.getOwnPropertyNames(require('events').EventEmitter.prototype)\n .filter(name => !name.startsWith('_'))\n .concat(['kill', 'ref', 'unref'])\n\nconst eos = (stream, listener, buffer = []) =>\n stream[listener] ? stream[listener].on('data', data => buffer.push(data)) && buffer : buffer\n\nconst createChildProcessError = ({ cmd, cmdArgs, childProcess }) => {\n const command = `${cmd} ${cmdArgs.join(' ')}`\n let message = `The command spawned as:${EOL}${EOL}`\n message += ` \\`${command}\\`${EOL}${EOL}`\n message += `exited with:${EOL}${EOL}`\n message += ` \\`{ signal: '${childProcess.signalCode}', code: ${childProcess.exitCode} }\\` ${EOL}${EOL}`\n message += `with the following trace:${EOL}`\n const error = new Error(message)\n error.command = command\n error.name = 'ChildProcessError'\n\n Object.keys(childProcess)\n .filter(key => !key.startsWith('_') && !['stdio', 'stdin'].includes(key))\n .forEach(key => {\n error[key] = childProcess[key]\n })\n\n return error\n}\n\nconst clean = str => str.trim().replace(/\\n$/, '')\n\nconst parse =\n (buffer, { json } = {}) =>\n (encoding, start, end) => {\n const data = clean(Buffer.concat(buffer).toString(encoding, start, end))\n return json ? JSON.parse(data) : data\n }\n\nconst extend = defaults => (input, args, options) => {\n if (!(args instanceof Array)) {\n options = args\n args = []\n }\n const [cmd, ...cmdArgs] = input.split(' ').concat(args).filter(Boolean)\n let childProcess\n\n const promise = new Promise((resolve, reject) => {\n const opts = { ...defaults, ...options }\n childProcess = spawn(cmd, cmdArgs, opts)\n const stdout = eos(childProcess, 'stdout')\n const stderr = eos(childProcess, 'stderr')\n\n childProcess.on('error', reject).on('exit', exitCode => {\n Object.defineProperty(childProcess, 'stdout', {\n get: parse(stdout, opts)\n })\n Object.defineProperty(childProcess, 'stderr', { get: parse(stderr) })\n return exitCode === 0\n ? resolve(childProcess)\n : reject(createChildProcessError({ cmd, cmdArgs, childProcess }))\n })\n })\n\n const subprocess = Object.assign(promise, childProcess)\n if (childProcess) {\n EE_PROPS.forEach(name => (subprocess[name] = childProcess[name].bind(childProcess)))\n }\n return subprocess\n}\n\nconst $ = extend()\n$.extend = extend\n$.json = $.extend({ json: true })\n\nmodule.exports = $\n","'use strict'\n\nmodule.exports = (platform = '') => {\n platform = platform.toLowerCase()\n return (\n [\n 'aix',\n 'android',\n 'darwin',\n 'freebsd',\n 'linux',\n 'openbsd',\n 'sunos'\n ].indexOf(platform) !== -1\n )\n}\n","'use strict'\n\nconst isUnix = require('is-unix')\nconst path = require('path')\n\nconst PLATFORM_WIN = 'win32'\nconst PLATFORM_UNIX = 'unix'\n\nfunction get (key) {\n if (!key) return undefined\n return (\n process.env[key] ??\n process.env[`npm_config_${key.toLowerCase()}`] ??\n process.env[`npm_config_${key.toUpperCase()}`]\n )\n}\n\nconst YOUTUBE_DL_HOST =\n get('YOUTUBE_DL_HOST') ??\n 'https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest'\n\nconst YOUTUBE_DL_DIR =\n get('YOUTUBE_DL_DIR') ?? path.join(__dirname, '..', 'bin')\n\nconst YOUTUBE_DL_PLATFORM =\n get('YOUTUBE_DL_PLATFORM') ?? isUnix(process.platform)\n ? PLATFORM_UNIX\n : PLATFORM_WIN\n\nconst YOUTUBE_DL_FILENAME = get('YOUTUBE_DL_FILENAME') || 'yt-dlp'\n\nconst YOUTUBE_DL_FILE =\n !YOUTUBE_DL_FILENAME.endsWith('.exe') && YOUTUBE_DL_PLATFORM === 'win32'\n ? `${YOUTUBE_DL_FILENAME}.exe`\n : YOUTUBE_DL_FILENAME\n\nconst YOUTUBE_DL_PATH = path.join(YOUTUBE_DL_DIR, YOUTUBE_DL_FILE)\n\nconst YOUTUBE_DL_SKIP_DOWNLOAD = get('YOUTUBE_DL_SKIP_DOWNLOAD')\n\nmodule.exports = {\n YOUTUBE_DL_DIR,\n YOUTUBE_DL_FILE,\n YOUTUBE_DL_FILENAME,\n YOUTUBE_DL_HOST,\n YOUTUBE_DL_PATH,\n YOUTUBE_DL_PLATFORM,\n YOUTUBE_DL_SKIP_DOWNLOAD\n}\n","'use strict'\n\nconst dargs = require('dargs')\nconst $ = require('tinyspawn')\n\nconst constants = require('./constants')\n\nconst args = (flags = {}) => dargs(flags, { useEquals: false }).filter(Boolean)\n\nconst isJSON = (str = '') => str.startsWith('{')\n\nconst parse = ({ stdout, stderr, ...details }) => {\n if (details.exitCode === 0) { return isJSON(stdout) ? JSON.parse(stdout) : stdout }\n throw Object.assign(new Error(stderr), { stderr, stdout }, details)\n}\n\nconst create = binaryPath => {\n const fn = (...args) =>\n fn\n .exec(...args)\n .then(parse)\n .catch(parse)\n fn.exec = (url, flags, opts) => $(binaryPath, [url].concat(args(flags)), opts)\n return fn\n}\n\nconst defaultInstance = create(constants.YOUTUBE_DL_PATH)\n\nmodule.exports = defaultInstance\nmodule.exports.youtubeDl = defaultInstance\nmodule.exports.create = create\nmodule.exports.args = args\nmodule.exports.isJSON = isJSON\nmodule.exports.constants = constants\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { GetObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\nimport {\n type IAgentRuntime,\n type IFileService,\n Service,\n type ServiceTypeName,\n ServiceType,\n logger,\n} from '@elizaos/core';\n\n/**\n * Interface representing the result of an upload operation.\n * @typedef {Object} UploadResult\n * @property {boolean} success - Indicates if the upload was successful or not.\n * @property {string} [url] - The URL of the uploaded file (optional).\n * @property {string} [error] - The error message in case the upload was unsuccessful (optional).\n */\ninterface UploadResult {\n success: boolean;\n url?: string;\n error?: string;\n}\n\n/**\n * Interface for the result of uploading a JSON file.\n * Extends UploadResult interface.\n *\n * @property {string} [key] - Optional storage key for the uploaded file.\n */\ninterface JsonUploadResult extends UploadResult {\n key?: string; // Add storage key\n}\n\n/**\n * Represents a service for interacting with AWS S3 to upload, download, and manage files.\n * @implements {IFileService}\n */\nexport class AwsS3Service extends Service implements IFileService {\n static serviceType: ServiceTypeName = ServiceType.REMOTE_FILES;\n capabilityDescription = 'The agent is able to upload and download files from AWS S3';\n\n private s3Client: S3Client | null = null;\n private bucket = '';\n private fileUploadPath = '';\n protected runtime: IAgentRuntime | null = null;\n\n /**\n * Constructor for a new instance of a class.\n * @param {IAgentRuntime} runtime - The runtime object for the agent.\n */\n constructor(runtime: IAgentRuntime) {\n super();\n this.runtime = runtime;\n this.fileUploadPath = runtime.getSetting('AWS_S3_UPLOAD_PATH') ?? '';\n }\n\n /**\n * Initializes AwsS3Service with the given runtime and settings.\n * @param {IAgentRuntime} runtime - The runtime object\n * @returns {Promise<AwsS3Service>} - The AwsS3Service instance\n */\n static async start(runtime: IAgentRuntime): Promise<AwsS3Service> {\n logger.log('Initializing AwsS3Service');\n const service = new AwsS3Service(runtime);\n service.runtime = runtime;\n service.fileUploadPath = runtime.getSetting('AWS_S3_UPLOAD_PATH') ?? '';\n return service;\n }\n\n /**\n * Stops the remote file service.\n *\n * @param {IAgentRuntime} runtime - The agent runtime\n * @returns {Promise<void>} - A promise that resolves once the service is stopped\n */\n static async stop(runtime: IAgentRuntime) {\n const service = runtime.getService(ServiceType.REMOTE_FILES);\n if (service) {\n await service.stop();\n }\n }\n\n /**\n * Asynchronously stops the S3 client if it exists by destroying the client and setting it to null.\n */\n async stop() {\n if (this.s3Client) {\n await this.s3Client.destroy();\n this.s3Client = null;\n }\n }\n\n /**\n * Initializes the S3 client with the provided settings.\n * If the S3 client is already initialized, it returns true.\n * If any required setting is missing or invalid, it returns false.\n *\n * @returns A Promise that resolves to true if the S3 client is successfully initialized, false otherwise.\n */\n private async initializeS3Client(): Promise<boolean> {\n if (this.s3Client) return true;\n if (!this.runtime) return false;\n\n const AWS_ACCESS_KEY_ID = this.runtime.getSetting('AWS_ACCESS_KEY_ID');\n const AWS_SECRET_ACCESS_KEY = this.runtime.getSetting('AWS_SECRET_ACCESS_KEY');\n const AWS_REGION = this.runtime.getSetting('AWS_REGION');\n const AWS_S3_BUCKET = this.runtime.getSetting('AWS_S3_BUCKET');\n\n if (!AWS_ACCESS_KEY_ID || !AWS_SECRET_ACCESS_KEY || !AWS_REGION || !AWS_S3_BUCKET) {\n return false;\n }\n\n // Optional fields to allow for other providers\n const endpoint = this.runtime.getSetting('AWS_S3_ENDPOINT');\n const sslEnabled = this.runtime.getSetting('AWS_S3_SSL_ENABLED');\n const forcePathStyle = this.runtime.getSetting('AWS_S3_FORCE_PATH_STYLE');\n\n this.s3Client = new S3Client({\n ...(endpoint ? { endpoint } : {}),\n ...(sslEnabled ? { sslEnabled } : {}),\n ...(forcePathStyle ? { forcePathStyle: Boolean(forcePathStyle) } : {}),\n region: AWS_REGION,\n credentials: {\n accessKeyId: AWS_ACCESS_KEY_ID,\n secretAccessKey: AWS_SECRET_ACCESS_KEY,\n },\n });\n this.bucket = AWS_S3_BUCKET;\n return true;\n }\n\n /**\n * Uploads a file to AWS S3 with optional configuration options.\n * @param {string} filePath - The path to the file to upload.\n * @param {string} [subDirectory=\"\"] - The subdirectory within the bucket to upload the file to.\n * @param {boolean} [useSignedUrl=false] - Indicates whether to use a signed URL for the file.\n * @param {number} [expiresIn=900] - The expiration time in seconds for the signed URL.\n * @returns {Promise<UploadResult>} A promise that resolves to an object containing the upload result.\n */\n async uploadFile(\n filePath: string,\n subDirectory = '',\n useSignedUrl = false,\n expiresIn = 900\n ): Promise<UploadResult> {\n try {\n if (!(await this.initializeS3Client())) {\n return {\n success: false,\n error: 'AWS S3 credentials not configured',\n };\n }\n\n if (!fs.existsSync(filePath)) {\n return {\n success: false,\n error: 'File does not exist',\n };\n }\n\n const fileContent = fs.readFileSync(filePath);\n\n const baseFileName = `${Date.now()}-${path.basename(filePath)}`;\n // Determine storage path based on public access\n const fileName = `${this.fileUploadPath}${subDirectory}/${baseFileName}`.replaceAll(\n '//',\n '/'\n );\n // Set upload parameters\n const uploadParams = {\n Bucket: this.bucket,\n Key: fileName,\n Body: fileContent,\n ContentType: this.getContentType(filePath),\n };\n\n // Upload file\n await this.s3Client.send(new PutObjectCommand(uploadParams));\n\n // Build result object\n const result: UploadResult = {\n success: true,\n };\n\n // If not using signed URL, return either custom endpoint or public access URL\n if (!useSignedUrl) {\n if (this.s3Client.config.endpoint) {\n const endpoint = await this.s3Client.config.endpoint();\n const port = endpoint.port ? `:${endpoint.port}` : '';\n result.url = `${endpoint.protocol}//${endpoint.hostname}${port}${endpoint.path}${this.bucket}/${fileName}`;\n } else {\n result.url = `https://${this.bucket}.s3.${process.env.AWS_REGION}.amazonaws.com/${fileName}`;\n }\n } else {\n const getObjectCommand = new GetObjectCommand({\n Bucket: this.bucket,\n Key: fileName,\n });\n result.url = await getSignedUrl(this.s3Client, getObjectCommand, {\n expiresIn, // 15 minutes in seconds\n });\n }\n\n return result;\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error occurred',\n };\n }\n }\n\n /**\n * Generate signed URL for existing file\n */\n /**\n * Generates a signed URL for accessing the specified file in the S3 bucket.\n *\n * @param {string} fileName - The name of the file to generate a signed URL for.\n * @param {number} expiresIn - The expiration time in seconds for the signed URL (default is 900 seconds).\n * @returns {Promise<string>} A promise that resolves with the signed URL for accessing the file.\n * @throws {Error} If AWS S3 credentials are not configured properly.\n */\n async generateSignedUrl(fileName: string, expiresIn = 900): Promise<string> {\n if (!(await this.initializeS3Client())) {\n throw new Error('AWS S3 credentials not configured');\n }\n\n const command = new GetObjectCommand({\n Bucket: this.bucket,\n Key: fileName,\n });\n\n return await getSignedUrl(this.s3Client, command, { expiresIn });\n }\n\n private getContentType(filePath: string): string {\n const ext = path.extname(filePath).toLowerCase();\n const contentTypes: { [key: string]: string } = {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n };\n return contentTypes[ext] || 'application/octet-stream';\n }\n\n /**\n * Upload JSON object to S3\n * @param jsonData JSON data to upload\n * @param fileName File name (optional, without path)\n * @param subDirectory Subdirectory (optional)\n * @param useSignedUrl Whether to use signed URL\n * @param expiresIn Signed URL expiration time (seconds)\n */\n async uploadJson(\n jsonData: any,\n fileName?: string,\n subDirectory?: string,\n useSignedUrl = false,\n expiresIn = 900\n ): Promise<JsonUploadResult> {\n try {\n if (!(await this.initializeS3Client())) {\n return {\n success: false,\n error: 'AWS S3 credentials not configured',\n };\n }\n\n // Validate input\n if (!jsonData) {\n return {\n success: false,\n error: 'JSON data is required',\n };\n }\n\n // Generate filename (if not provided)\n const timestamp = Date.now();\n const actualFileName = fileName || `${timestamp}.json`;\n\n // Build complete file path\n let fullPath = this.fileUploadPath || '';\n if (subDirectory) {\n fullPath = `${fullPath}/${subDirectory}`.replace(/\\/+/g, '/');\n }\n const key = `${fullPath}/${actualFileName}`.replace(/\\/+/g, '/');\n\n // Convert JSON to string\n const jsonString = JSON.stringify(jsonData, null, 2);\n\n // Set upload parameters\n const uploadParams = {\n Bucket: this.bucket,\n Key: key,\n Body: jsonString,\n ContentType: 'application/json',\n };\n\n // Upload file\n await this.s3Client.send(new PutObjectCommand(uploadParams));\n\n // Build result\n const result: JsonUploadResult = {\n success: true,\n key: key,\n };\n\n // If not using signed URL, return either custom endpoint or public access URL\n if (!useSignedUrl) {\n if (this.s3Client.config.endpoint) {\n const endpoint = await this.s3Client.config.endpoint();\n const port = endpoint.port ? `:${endpoint.port}` : '';\n result.url = `${endpoint.protocol}//${endpoint.hostname}${port}${endpoint.path}${this.bucket}/${key}`;\n } else {\n result.url = `https://${this.bucket}.s3.${process.env.AWS_REGION}.amazonaws.com/${key}`;\n }\n } else {\n const getObjectCommand = new GetObjectCommand({\n Bucket: this.bucket,\n Key: key,\n });\n result.url = await getSignedUrl(this.s3Client, getObjectCommand, {\n expiresIn,\n });\n }\n\n return result;\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error occurred',\n };\n }\n }\n}\n\nexport default AwsS3Service;\n","import {\n type IAgentRuntime,\n type IBrowserService,\n ModelType,\n Service,\n type ServiceTypeName,\n ServiceType,\n logger,\n parseJSONObjectFromText,\n stringToUuid,\n trimTokens,\n} from '@elizaos/core';\nimport CaptchaSolver from 'capsolver-npm';\nimport { type Browser, type BrowserContext, type Page, chromium } from 'patchright';\n\n/**\n * Asynchronously generates a summary for a given text using a machine learning model.\n *\n * @param {IAgentRuntime} runtime - The runtime environment for the agent\n * @param {string} text - The text to generate a summary for\n * @returns {Promise<{ title: string; description: string }>} A promise that resolves to an object containing the generated title and summary\n */\nasync function generateSummary(\n runtime: IAgentRuntime,\n text: string\n): Promise<{ title: string; description: string }> {\n // make sure text is under 128k characters\n text = await trimTokens(text, 100000, runtime);\n\n const prompt = `Please generate a concise summary for the following text:\n\n Text: \"\"\"\n ${text}\n \"\"\"\n\n Respond with a JSON object in the following format:\n \\`\\`\\`json\n {\n \"title\": \"Generated Title\",\n \"summary\": \"Generated summary and/or description of the text\"\n }\n \\`\\`\\``;\n\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsedResponse = parseJSONObjectFromText(response);\n\n if (parsedResponse?.title && parsedResponse?.summary) {\n return {\n title: parsedResponse.title,\n description: parsedResponse.summary,\n };\n }\n\n return {\n title: '',\n description: '',\n };\n}\n\n/**\n * Represents the content of a page.\n * @typedef { Object } PageContent\n * @property { string } title - The title of the page.\n * @property { string } description - The description of the page.\n * @property { string } bodyContent - The main content of the page.\n */\ntype PageContent = {\n title: string;\n description: string;\n bodyContent: string;\n};\n\n/**\n * Represents a BrowserService class that extends Service and implements IBrowserService interface.\n * Provides methods for initializing browser, stopping browser, fetching page content, solving CAPTCHAs, detecting CAPTCHAs, and getting cache key.\n * @extends Service\n * @implements IBrowserService\n */\nexport class BrowserService extends Service implements IBrowserService {\n private browser: Browser | undefined;\n private context: BrowserContext | undefined;\n private captchaSolver: CaptchaSolver;\n private cacheKey = 'content/browser';\n\n static serviceType: ServiceTypeName = ServiceType.BROWSER;\n capabilityDescription = 'The agent is able to browse the web and fetch content';\n\n /**\n * Constructor for the Agent class.\n * @param {IAgentRuntime} runtime - The runtime object for the agent.\n */\n constructor(runtime: IAgentRuntime) {\n super();\n this.runtime = runtime;\n this.browser = undefined;\n this.context = undefined;\n this.captchaSolver = new CaptchaSolver(runtime.getSetting('CAPSOLVER_API_KEY') || '');\n }\n\n /**\n * Starts the BrowserService asynchronously.\n *\n * @param {IAgentRuntime} runtime - The runtime for the agent.\n * @returns {Promise<BrowserService>} A promise that resolves to the initialized BrowserService.\n */\n static async start(runtime: IAgentRuntime): Promise<BrowserService> {\n const service = new BrowserService(runtime);\n await service.initializeBrowser();\n return service;\n }\n\n /**\n * Function to stop the browser service asynchronously.\n *\n * @param {IAgentRuntime} runtime - The runtime environment for the agent.\n */\n static async stop(runtime: IAgentRuntime) {\n const service = runtime.getService(ServiceType.BROWSER);\n if (service) {\n await service.stop();\n }\n }\n\n /**\n * Initializes the browser by launching Chromium with specified options and setting the user agent based on the platform.\n * @returns {Promise<void>} A promise that resolves once the browser is successfully initialized.\n */\n async initializeBrowser() {\n if (!this.browser) {\n this.browser = await chromium.launch({\n headless: true,\n args: [\n '--disable-dev-shm-usage', // Uses /tmp instead of /dev/shm. Prevents memory issues on low-memory systems\n '--block-new-web-contents', // Prevents creation of new windows/tabs\n ],\n });\n\n const platform = process.platform;\n let userAgent = '';\n\n // Change the user agent to match the platform to reduce bot detection\n switch (platform) {\n case 'darwin':\n userAgent =\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\n break;\n case 'win32':\n userAgent =\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\n break;\n case 'linux':\n userAgent =\n 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\n break;\n default:\n userAgent =\n 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\n }\n\n this.context = await this.browser.newContext({\n userAgent,\n acceptDownloads: false,\n });\n }\n }\n\n /**\n * Asynchronously stops the browser and context if they are currently running.\n */\n async stop() {\n if (this.context) {\n await this.context.close();\n this.context = undefined;\n }\n if (this.browser) {\n await this.browser.close();\n this.browser = undefined;\n }\n }\n\n /**\n * Asynchronously fetches the content of a web page.\n *\n * @param {string} url - The URL of the web page to fetch content from.\n * @param {IAgentRuntime} runtime - The runtime environment for the web scraping agent.\n * @returns {Promise<PageContent>} A Promise that resolves with the content of the web page.\n */\n async getPageContent(url: string, runtime: IAgentRuntime): Promise<PageContent> {\n await this.initializeBrowser();\n return await this.fetchPageContent(url, runtime);\n }\n\n /**\n * Generates a cache key for the provided URL by converting it to a UUID string.\n *\n * @param {string} url - The URL for which a cache key is being generated.\n * @returns {string} A UUID string representing the cache key for the URL.\n */\n private getCacheKey(url: string): string {\n return stringToUuid(url);\n }\n\n /**\n * Fetches the content of a page from the specified URL using a headless browser.\n *\n * @param {string} url - The URL of the page to fetch the content from.\n * @param {IAgentRuntime} runtime - The runtime environment for the agent.\n * @returns {Promise<PageContent>} A promise that resolves to the content of the fetched page.\n */\n private async fetchPageContent(url: string, runtime: IAgentRuntime): Promise<PageContent> {\n const cacheKey = this.getCacheKey(url);\n const cached = await runtime.getCache<any>(`${this.cacheKey}/${cacheKey}`);\n\n if (cached) {\n return cached.content;\n }\n\n let page: Page | undefined;\n\n try {\n if (!this.context) {\n logger.log('Browser context not initialized. Call initializeBrowser() first.');\n }\n\n page = await this.context.newPage();\n\n // Enable stealth mode\n await page.setExtraHTTPHeaders({\n 'Accept-Language': 'en-US,en;q=0.9',\n });\n\n const response = await page.goto(url, { waitUntil: 'networkidle' });\n\n if (!response) {\n logger.error('Failed to load the page');\n }\n\n if (response.status() === 403 || response.status() === 404) {\n return await this.tryAlternativeSources(url, runtime);\n }\n\n // Check for CAPTCHA\n const captchaDetected = await this.detectCaptcha(page);\n if (captchaDetected) {\n await this.solveCaptcha(page, url);\n }\n const documentTitle = await page.evaluate(() => document.title);\n const bodyContent = await page.evaluate(() => document.body.innerText);\n const { title: parsedTitle, description } = await generateSummary(\n runtime,\n `${documentTitle}\\n${bodyContent}`\n );\n const content = { title: parsedTitle, description, bodyContent };\n await runtime.setCache<any>(`${this.cacheKey}/${cacheKey}`, {\n url,\n content,\n });\n return content;\n } catch (error) {\n logger.error('Error:', error);\n return {\n title: url,\n description: 'Error, could not fetch content',\n bodyContent: '',\n };\n } finally {\n if (page) {\n await page.close();\n }\n }\n }\n\n /**\n * Detects if a captcha is present on the page based on the specified selectors.\n *\n * @param {Page} page The Puppeteer page to check for captcha.\n * @returns {Promise<boolean>} A boolean indicating whether a captcha was detected.\n */\n private async detectCaptcha(page: Page): Promise<boolean> {\n const captchaSelectors = [\n 'iframe[src*=\"captcha\"]',\n 'div[class*=\"captcha\"]',\n '#captcha',\n '.g-recaptcha',\n '.h-captcha',\n ];\n\n for (const selector of captchaSelectors) {\n const element = await page.$(selector);\n if (element) return true;\n }\n\n return false;\n }\n\n /**\n * Solves the CAPTCHA challenge on the provided page using either hCaptcha or reCaptcha.\n *\n * @param {Page} page - The page where the CAPTCHA challenge needs to be solved.\n * @param {string} url - The URL of the website with the CAPTCHA challenge.\n * @returns {Promise<void>} - A promise that resolves once the CAPTCHA is solved.\n */\n private async solveCaptcha(page: Page, url: string): Promise<void> {\n try {\n const hcaptchaKey = await this.getHCaptchaWebsiteKey(page);\n if (hcaptchaKey) {\n const solution = await this.captchaSolver.hcaptchaProxyless({\n websiteURL: url,\n websiteKey: hcaptchaKey,\n });\n await page.evaluate((token) => {\n // eslint-disable-next-line\n // @ts-ignore\n window.hcaptcha.setResponse(token);\n }, solution.gRecaptchaResponse);\n return;\n }\n\n const recaptchaKey = await this.getReCaptchaWebsiteKey(page);\n if (recaptchaKey) {\n const solution = await this.captchaSolver.recaptchaV2Proxyless({\n websiteURL: url,\n websiteKey: recaptchaKey,\n });\n await page.evaluate((token) => {\n // eslint-disable-next-line\n // @ts-ignore\n document.getElementById('g-recaptcha-response').innerHTML = token;\n }, solution.gRecaptchaResponse);\n }\n } catch (error) {\n logger.error('Error solving CAPTCHA:', error);\n }\n }\n\n /**\n * Get the hCaptcha website key from the given Page\n * @param {Page} page - The Page object to extract the hCaptcha website key from\n * @returns {Promise<string>} The hCaptcha website key\n */\n private async getHCaptchaWebsiteKey(page: Page): Promise<string> {\n return page.evaluate(() => {\n const hcaptchaIframe = document.querySelector('iframe[src*=\"hcaptcha.com\"]');\n if (hcaptchaIframe) {\n const src = hcaptchaIframe.getAttribute('src');\n const match = src?.match(/sitekey=([^&]*)/);\n return match ? match[1] : '';\n }\n return '';\n });\n }\n\n /**\n * Retrieves the ReCaptcha website key from a given page.\n * @param {Page} page - The page to extract the ReCaptcha website key from.\n * @returns {Promise<string>} The ReCaptcha website key, or an empty string if not found.\n */\n private async getReCaptchaWebsiteKey(page: Page): Promise<string> {\n return page.evaluate(() => {\n const recaptchaElement = document.querySelector('.g-recaptcha');\n return recaptchaElement ? recaptchaElement.getAttribute('data-sitekey') || '' : '';\n });\n }\n\n /**\n * Try fetching content from alternative sources if the original source fails.\n *\n * @param {string} url - The URL of the content to fetch.\n * @param {IAgentRuntime} runtime - The runtime environment.\n * @returns {Promise<{ title: string; description: string; bodyContent: string }>} The fetched content with title, description, and body.\n */\n private async tryAlternativeSources(\n url: string,\n runtime: IAgentRuntime\n ): Promise<{ title: string; description: string; bodyContent: string }> {\n // because this (tryAlternativeSources) calls fetchPageContent\n // and fetchPageContent calls tryAlternativeSources\n // we need these url.matches to progress\n // through the things to try\n if (!url.match(/web.archive.org\\/web/)) {\n // Try Internet Archive\n const archiveUrl = `https://web.archive.org/web/${url}`;\n try {\n return await this.fetchPageContent(archiveUrl, runtime);\n } catch (error) {\n logger.error('Error fetching from Internet Archive:', error);\n }\n }\n\n if (!url.match(/www.google.com\\/search/)) {\n // Try Google Search as a last resort\n const googleSearchUrl = `https://www.google.com/search?q=${encodeURIComponent(url)}`;\n try {\n return await this.fetchPageContent(googleSearchUrl, runtime);\n } catch (error) {\n logger.error('Error fetching from Google Search:', error);\n logger.error('Failed to fetch content from alternative sources');\n return {\n title: url,\n description: 'Error, could not fetch content from alternative sources',\n bodyContent: '',\n };\n }\n }\n }\n}\n","import {\n type IAgentRuntime,\n type IPdfService,\n Service,\n type ServiceTypeName,\n ServiceType,\n} from '@elizaos/core';\nimport { type PDFDocumentProxy, getDocument } from 'pdfjs-dist';\nimport type { TextItem, TextMarkedContent } from 'pdfjs-dist/types/src/display/api';\n\n/**\n * Class representing a PDF service that can convert PDF files to text.\n * * @extends Service\n * @implements IPdfService\n */\nexport class PdfService extends Service implements IPdfService {\n static serviceType: ServiceTypeName = ServiceType.PDF;\n capabilityDescription = 'The agent is able to convert PDF files to text';\n\n /**\n * Constructor for creating a new instance of the class.\n *\n * @param {IAgentRuntime} runtime - The runtime object passed to the constructor.\n */\n constructor(runtime: IAgentRuntime) {\n super();\n this.runtime = runtime;\n }\n\n /**\n * Starts the PdfService asynchronously.\n * @param {IAgentRuntime} runtime - The runtime object for the agent.\n * @returns {Promise<PdfService>} A promise that resolves with the PdfService instance.\n */\n static async start(runtime: IAgentRuntime): Promise<PdfService> {\n const service = new PdfService(runtime);\n return service;\n }\n\n /**\n * Stop the PDF service in the given runtime.\n *\n * @param {IAgentRuntime} runtime - The runtime to stop the PDF service in.\n * @returns {Promise<void>} - A promise that resolves once the PDF service is stopped.\n */\n static async stop(runtime: IAgentRuntime) {\n const service = runtime.getService(ServiceType.PDF);\n if (service) {\n await service.stop();\n }\n }\n\n /**\n * Asynchronously stops the process.\n * Does nothing.\n */\n async stop() {\n // do nothing\n }\n\n /**\n * Converts a PDF Buffer to text.\n *\n * @param {Buffer} pdfBuffer - The PDF Buffer to convert to text.\n * @returns {Promise<string>} A Promise that resolves with the text content of the PDF.\n */\n async convertPdfToText(pdfBuffer: Buffer): Promise<string> {\n // Convert Buffer to Uint8Array\n const uint8Array = new Uint8Array(pdfBuffer);\n\n const pdf: PDFDocumentProxy = await getDocument({ data: uint8Array }).promise;\n const numPages = pdf.numPages;\n const textPages: string[] = [];\n\n for (let pageNum = 1; pageNum <= numPages; pageNum++) {\n const page = await pdf.getPage(pageNum);\n const textContent = await page.getTextContent();\n const pageText = textContent.items\n .filter(isTextItem)\n .map((item) => item.str)\n .join(' ');\n textPages.push(pageText);\n }\n\n return textPages.join('\\n');\n }\n}\n\n// Type guard function\n/**\n * Check if the input is a TextItem.\n *\n * @param item - The input item to check.\n * @returns A boolean indicating if the input is a TextItem.\n */\nfunction isTextItem(item: TextItem | TextMarkedContent): item is TextItem {\n return 'str' in item;\n}\n","import fs from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\nimport {\n type IAgentRuntime,\n type IVideoService,\n type Media,\n ModelType,\n Service,\n type ServiceTypeName,\n ServiceType,\n logger,\n stringToUuid,\n} from '@elizaos/core';\nimport ffmpeg from 'fluent-ffmpeg';\nimport ytdl, { create } from 'youtube-dl-exec';\n\n/**\n * Function to get the Youtube DL executable path.\n * It first checks if /usr/local/bin/yt-dlp exists,\n * if it does, it returns the path to that executable.\n * If not, it checks if /usr/bin/yt-dlp exists,\n * and returns the path if found.\n * If neither paths exist, it returns the default ytdl executable.\n * @returns {string} The path to the Youtube DL executable.\n */\nfunction getYoutubeDL() {\n // first check if /usr/local/bin/yt-dlp exists\n if (fs.existsSync('/usr/local/bin/yt-dlp')) {\n return create('/usr/local/bin/yt-dlp');\n }\n\n // if not, check if /usr/bin/yt-dlp exists\n if (fs.existsSync('/usr/bin/yt-dlp')) {\n return create('/usr/bin/yt-dlp');\n }\n\n // use default otherwise\n return ytdl;\n}\n\n/**\n * VideoService class that extends Service and implements IVideoService interface.\n * Defines the service type as VIDEO and sets capability description for processing videos.\n * Manages caching of video content with cacheKey and dataDir properties.\n * Maintains a queue of video processing tasks and tracks processing status.\n */\nexport class VideoService extends Service implements IVideoService {\n static serviceType: ServiceTypeName = ServiceType.VIDEO;\n capabilityDescription = 'The agent is able to download and process videos';\n private cacheKey = 'content/video';\n private dataDir = './cache';\n\n private queue: string[] = [];\n private processing = false;\n\n /**\n * Constructor for creating a new instance of the object.\n *\n * @param {IAgentRuntime} runtime - The runtime object to be used by the instance\n */\n constructor(runtime: IAgentRuntime) {\n super();\n this.runtime = runtime;\n this.ensureDataDirectoryExists();\n }\n\n /**\n * Starts the VideoService by initializing it with the given IAgentRuntime instance.\n *\n * @param {IAgentRuntime} runtime - The IAgentRuntime instance to initialize the service with.\n * @returns {Promise<VideoService>} A promise that resolves to the initialized VideoService instance.\n */\n static async start(runtime: IAgentRuntime): Promise<VideoService> {\n const service = new VideoService(runtime);\n return service;\n }\n\n /**\n * Stops the video service if it is running.\n *\n * @param {IAgentRuntime} runtime - The agent runtime instance\n * @returns {Promise<void>} A promise that resolves once the video service is stopped\n */\n static async stop(runtime: IAgentRuntime) {\n const service = runtime.getService(ServiceType.VIDEO);\n if (service) {\n await service.stop();\n }\n }\n\n /**\n * Asynchronous method to stop the operation.\n */\n async stop() {\n // do nothing\n }\n\n /**\n * Checks if the data directory exists, and if not, creates it.\n */\n private ensureDataDirectoryExists() {\n if (!fs.existsSync(this.dataDir)) {\n fs.mkdirSync(this.dataDir);\n }\n }\n\n /**\n * Check if a given URL is a video URL from YouTube or Vimeo.\n *\n * @param {string} url - The URL to check.\n * @return {boolean} Returns true if the URL is from YouTube or Vimeo, false otherwise.\n */\n public isVideoUrl(url: string): boolean {\n return url.includes('youtube.com') || url.includes('youtu.be') || url.includes('vimeo.com');\n }\n\n /**\n * Downloads media from a given URL. If the media already exists, it returns the file path.\n *\n * @param {string} url - The URL of the media to download.\n * @returns {Promise<string>} A promise that resolves to the file path of the downloaded media.\n * @throws {Error} If there is an error downloading the media.\n */\n public async downloadMedia(url: string): Promise<string> {\n const videoId = this.getVideoId(url);\n const outputFile = path.join(this.dataDir, `${videoId}.mp4`);\n\n // if it already exists, return it\n if (fs.existsSync(outputFile)) {\n return outputFile;\n }\n\n try {\n await getYoutubeDL()(url, {\n verbose: true,\n output: outputFile,\n writeInfoJson: true,\n });\n return outputFile;\n } catch (error) {\n logger.log('Error downloading media:', error);\n throw new Error('Failed to download media');\n }\n }\n\n /**\n * Downloads a video using the videoInfo object provided and returns the path to the downloaded video file.\n * If the video file already exists, it will return the path without re-downloading.\n * @param {Object} videoInfo - Information about the video to download.\n * @returns {Promise<string>} - Path to the downloaded video file.\n */\n public async downloadVideo(videoInfo: any): Promise<string> {\n const videoId = this.getVideoId(videoInfo.webpage_url);\n const outputFile = path.join(this.dataDir, `${videoId}.mp4`);\n\n // if it already exists, return it\n if (fs.existsSync(outputFile)) {\n return outputFile;\n }\n\n try {\n await getYoutubeDL()(videoInfo.webpage_url, {\n verbose: true,\n output: outputFile,\n format: 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',\n writeInfoJson: true,\n });\n return outputFile;\n } catch (error) {\n logger.log('Error downloading video:', error);\n throw new Error('Failed to download video');\n }\n }\n\n /**\n * Process a video from the given URL using the provided agent runtime.\n *\n * @param {string} url - The URL of the video to be processed\n * @param {IAgentRuntime} runtime - The agent runtime to be used for processing the video\n * @returns {Promise<Media>} A promise that resolves to the processed media\n */\n public async processVideo(url: string, runtime: IAgentRuntime): Promise<Media> {\n this.queue.push(url);\n await this.processQueue(runtime);\n\n return new Promise((resolve, reject) => {\n const checkQueue = async () => {\n const index = this.queue.indexOf(url);\n if (index !== -1) {\n setTimeout(checkQueue, 100);\n } else {\n this.processVideoFromUrl(url, runtime).then(resolve).catch(reject);\n }\n };\n checkQueue();\n });\n }\n\n /**\n * Processes the queue of URLs by calling processVideoFromUrl for each URL.\n *\n * @param {any} runtime - The runtime information for processing the videos.\n * @returns {Promise<void>} - A promise that resolves when the queue has been processed.\n */\n private async processQueue(runtime): Promise<void> {\n if (this.processing || this.queue.length === 0) {\n return;\n }\n\n this.processing = true;\n\n while (this.queue.length > 0) {\n const url = this.queue.shift()!;\n await this.processVideoFromUrl(url, runtime);\n }\n\n this.processing = false;\n }\n\n /**\n * Processes a video from a given URL.\n * Retrieves video information, transcript, and caches the result.\n *\n * @param {string} url - The URL of the video to process.\n * @param {IAgentRuntime} runtime - The runtime environment for the agent.\n * @returns {Promise<Media>} A promise that resolves to the processed video data.\n * @throws {Error} If there is an error processing the video.\n */\n private async processVideoFromUrl(url: string, runtime: IAgentRuntime): Promise<Media> {\n const videoId =\n url.match(\n /(?:youtu\\.be\\/|youtube\\.com(?:\\/embed\\/|\\/v\\/|\\/watch\\?v=|\\/watch\\?.+&v=))([^\\/&?]+)/ // eslint-disable-line\n )?.[1] || '';\n const videoUuid = this.getVideoId(videoId);\n const cacheKey = `${this.cacheKey}/${videoUuid}`;\n\n const cached = await runtime.getCache<Media>(cacheKey);\n\n if (cached) {\n logger.debug('Returning cached video file');\n return cached;\n }\n\n try {\n logger.debug('Fetching video info');\n const videoInfo = await this.fetchVideoInfo(url);\n logger.debug('Getting transcript');\n const transcript = await this.getTranscript(url, videoInfo, runtime);\n\n const result: Media = {\n id: videoUuid,\n url: url,\n title: videoInfo.title,\n source: videoInfo.channel,\n description: videoInfo.description,\n text: transcript,\n };\n\n await runtime.setCache<Media>(cacheKey, result);\n\n return result;\n } catch (error) {\n throw new Error(`Error processing video: ${error.message || error}`);\n }\n }\n\n /**\n * Returns the unique video ID generated from the provided URL.\n * @param {string} url - The URL used to generate the video ID.\n * @returns {string} The unique video ID.\n */\n private getVideoId(url: string): string {\n return stringToUuid(url);\n }\n\n /**\n * Asynchronously fetches video information from the provided URL. If the URL ends with \".mp4\" or includes \".mp4?\", attempts to fetch the video directly using fetch. If successful, returns a simplified video info object with title, description, and channel. If direct download fails, falls back to using youtube-dl to fetch video information. Utilizes options such as dumpJson, verbose, callHome, noCheckCertificates, preferFreeFormats, youtubeSkipDashManifest, writeSub, writeAutoSub, subLang, and skipDownload when calling youtube-dl. Throws an error if the response from youtube-dl is empty or if there is an error during the process.\n *\n * @param {string} url - The URL from which to fetch video information\n * @returns {Promise<any>} A Promise resolving to the fetched video information or rejecting with an error message\n */\n async fetchVideoInfo(url: string): Promise<any> {\n if (url.endsWith('.mp4') || url.includes('.mp4?')) {\n try {\n const response = await fetch(url);\n if (response.ok) {\n // If the URL is a direct link to an MP4 file, return a simplified video info object\n return {\n title: path.basename(url),\n description: '',\n channel: '',\n };\n }\n } catch (error) {\n logger.log('Error downloading MP4 file:', error);\n // Fall back to using youtube-dl if direct download fails\n }\n }\n\n try {\n const result = await getYoutubeDL()(url, {\n dumpJson: true,\n verbose: true,\n callHome: false,\n noCheckCertificates: true,\n preferFreeFormats: true,\n youtubeSkipDashManifest: true,\n writeSub: true,\n writeAutoSub: true,\n subLang: 'en',\n skipDownload: true,\n });\n\n if (!result || Object.keys(result).length === 0) {\n throw new Error('Empty response from youtube-dl');\n }\n\n return result;\n } catch (error) {\n throw new Error(`Failed to fetch video information: ${error.message || error}`);\n }\n }\n\n /**\n * Asynchronously retrieves the transcript of a video based on the provided URL, video information, and runtime environment.\n *\n * @param {string} url - The URL of the video.\n * @param {any} videoInfo - Information about the video, including subtitles, automatic captions, and categories.\n * @param {IAgentRuntime} runtime - The runtime environment of the agent.\n * @returns {Promise<string>} A Promise that resolves to the transcript of the video.\n */\n private async getTranscript(\n url: string,\n videoInfo: any,\n runtime: IAgentRuntime\n ): Promise<string> {\n logger.log('Getting transcript');\n try {\n // Check for manual subtitles\n if (videoInfo.subtitles?.en) {\n logger.log('Manual subtitles found');\n const srtContent = await this.downloadSRT(videoInfo.subtitles.en[0].url);\n return this.parseSRT(srtContent);\n }\n\n // Check for automatic captions\n if (videoInfo.automatic_captions?.en) {\n logger.log('Automatic captions found');\n const captionUrl = videoInfo.automatic_captions.en[0].url;\n const captionContent = await this.downloadCaption(captionUrl);\n return this.parseCaption(captionContent);\n }\n\n // Check if it's a music video\n if (videoInfo.categories?.includes('Music')) {\n logger.log('Music video detected, no lyrics available');\n return 'No lyrics available.';\n }\n\n // Fall back to audio transcription\n logger.log('No subtitles or captions found, falling back to audio transcription');\n return this.transcribeAudio(url, runtime);\n } catch (error) {\n logger.log('Error in getTranscript:', error);\n throw error;\n }\n }\n\n /**\n * Downloads a caption from the specified URL.\n * @param {string} url - The URL from which to download the caption.\n * @returns {Promise<string>} A promise that resolves with the downloaded caption as a string.\n * @throws {Error} If the caption download fails, an error is thrown with the reason.\n */\n private async downloadCaption(url: string): Promise<string> {\n logger.log('Downloading caption from:', url);\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to download caption: ${response.statusText}`);\n }\n return await response.text();\n }\n\n /**\n * Parses the given caption content to extract relevant information.\n *\n * @param {string} captionContent - The caption content to parse.\n * @returns {string} The extracted caption information as a string.\n */\n private parseCaption(captionContent: string): string {\n logger.log('Parsing caption');\n try {\n const jsonContent = JSON.parse(captionContent);\n if (jsonContent.events) {\n return jsonContent.events\n .filter((event) => event.segs)\n .map((event) => event.segs.map((seg) => seg.utf8).join(''))\n .join('')\n .replace('\\n', ' ');\n }\n logger.log('Unexpected caption format:', jsonContent);\n return 'Error: Unable to parse captions';\n } catch (error) {\n logger.log('Error parsing caption:', error);\n return 'Error: Unable to parse captions';\n }\n }\n\n /**\n * Parses SRT (SubRip) content to extract subtitles.\n *\n * @param {string} srtContent - The SRT content to parse.\n * @returns {string} The parsed subtitles as a single string.\n */\n private parseSRT(srtContent: string): string {\n // Simple SRT parser (replace with a more robust solution if needed)\n return srtContent\n .split('\\n\\n')\n .map((block) => block.split('\\n').slice(2).join(' '))\n .join(' ');\n }\n\n /**\n * Asynchronously downloads a SubRip subtitle file from the specified URL.\n *\n * @param {string} url - The URL of the subtitle file to download.\n * @returns {Promise<string>} A promise that resolves to the text content of the downloaded subtitle file.\n */\n private async downloadSRT(url: string): Promise<string> {\n logger.log('downloadSRT');\n const response = await fetch(url);\n return await response.text();\n }\n\n /**\n * Asynchronously transcribes audio from the provided URL using the agent runtime.\n *\n * @param {string} url - The URL of the audio file to transcribe.\n * @param {IAgentRuntime} runtime - The agent runtime to use for transcription.\n * @returns {Promise<string>} A promise that resolves with the transcription result, or \"Transcription failed\" if the process was unsuccessful.\n */\n async transcribeAudio(url: string, runtime: IAgentRuntime): Promise<string> {\n logger.log('Preparing audio for transcription...');\n\n // Check if ffmpeg exists in PATH\n try {\n await new Promise((resolve, reject) => {\n ffmpeg.getAvailableCodecs((err, _codecs) => {\n if (err) reject(err);\n resolve(null);\n });\n });\n } catch (error) {\n logger.log('FFmpeg not found:', error);\n return null;\n }\n\n const mp4FilePath = path.join(this.dataDir, `${this.getVideoId(url)}.mp4`);\n\n const webmFilePath = path.join(this.dataDir, `${this.getVideoId(url)}.webm`);\n\n const mp3FilePath = path.join(this.dataDir, `${this.getVideoId(url)}.mp3`);\n\n if (!fs.existsSync(mp3FilePath)) {\n if (fs.existsSync(webmFilePath)) {\n logger.log('WEBM file found. Converting to MP3...');\n await this.convertWebmToMp3(webmFilePath, mp3FilePath);\n } else if (fs.existsSync(mp4FilePath)) {\n logger.log('MP4 file found. Converting to MP3...');\n await this.convertMp4ToMp3(mp4FilePath, mp3FilePath);\n } else {\n logger.log('Downloading audio...');\n await this.downloadAudio(url, mp3FilePath);\n }\n }\n\n logger.log(`Audio prepared at ${mp3FilePath}`);\n\n const audioBuffer = fs.readFileSync(mp3FilePath);\n logger.log(`Audio file size: ${audioBuffer.length} bytes`);\n\n logger.log('Starting transcription...');\n const startTime = Date.now();\n const transcript = await runtime.useModel(ModelType.TRANSCRIPTION, audioBuffer);\n\n const endTime = Date.now();\n logger.log(`Transcription completed in ${(endTime - startTime) / 1000} seconds`);\n\n // Don't delete the MP3 file as it might be needed for future use\n return transcript || 'Transcription failed';\n }\n\n /**\n * Converts a given MP4 file to MP3 format.\n *\n * @param {string} inputPath - The path to the input MP4 file.\n * @param {string} outputPath - The desired path for the output MP3 file.\n * @returns {Promise<void>} A Promise that resolves once the conversion is complete or rejects with an error.\n */\n private async convertMp4ToMp3(inputPath: string, outputPath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n ffmpeg(inputPath)\n .output(outputPath)\n .noVideo()\n .audioCodec('libmp3lame')\n .on('end', () => {\n logger.log('Conversion to MP3 complete');\n resolve();\n })\n .on('error', (err) => {\n logger.log('Error converting to MP3:', err);\n reject(err);\n })\n .run();\n });\n }\n\n /**\n * Convert a WebM file to MP3 format.\n *\n * @param {string} inputPath - The path of the WebM file to convert.\n * @param {string} outputPath - The path where the MP3 file will be saved.\n * @returns {Promise<void>} Promise that resolves when the conversion is complete.\n */\n private async convertWebmToMp3(inputPath: string, outputPath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n ffmpeg(inputPath)\n .output(outputPath)\n .noVideo()\n .audioCodec('libmp3lame')\n .on('end', () => {\n logger.log('Conversion to MP3 complete');\n resolve();\n })\n .on('error', (err) => {\n logger.log('Error converting to MP3:', err);\n reject(err);\n })\n .run();\n });\n }\n\n /**\n * Downloads audio from a given URL and saves it to the specified output file.\n * If no output file is provided, it will default to saving the audio in the data directory with the video ID as the filename.\n * Supports downloading and converting MP4 files to MP3 as well as downloading audio from YouTube videos using youtube-dl.\n *\n * @param url - The URL of the audio to download.\n * @param outputFile - The path to save the downloaded audio file. If not provided, it defaults to saving in the data directory with the video ID as the filename.\n * @returns A Promise that resolves with the path to the downloaded audio file.\n * @throws Error if there is an issue during the download process.\n */\n private async downloadAudio(url: string, outputFile: string): Promise<string> {\n logger.log('Downloading audio');\n outputFile = outputFile ?? path.join(this.dataDir, `${this.getVideoId(url)}.mp3`);\n\n try {\n if (url.endsWith('.mp4') || url.includes('.mp4?')) {\n logger.log('Direct MP4 file detected, downloading and converting to MP3');\n const tempMp4File = path.join(tmpdir(), `${this.getVideoId(url)}.mp4`);\n const response = await fetch(url);\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n fs.writeFileSync(tempMp4File, buffer);\n\n await new Promise<void>((resolve, reject) => {\n ffmpeg(tempMp4File)\n .output(outputFile)\n .noVideo()\n .audioCodec('libmp3lame')\n .on('end', () => {\n fs.unlinkSync(tempMp4File);\n resolve();\n })\n .on('error', (err) => {\n reject(err);\n })\n .run();\n });\n } else {\n logger.log('YouTube video detected, downloading audio with youtube-dl');\n await getYoutubeDL()(url, {\n verbose: true,\n extractAudio: true,\n audioFormat: 'mp3',\n output: outputFile,\n writeInfoJson: true,\n });\n }\n return outputFile;\n } catch (error) {\n logger.log('Error downloading audio:', error);\n throw new Error('Failed to download audio');\n }\n }\n}\n","export * from './services/index';\n\nimport type { Plugin } from '@elizaos/core';\n\nimport { AwsS3Service, BrowserService, PdfService, VideoService } from './services/index';\n\nexport const nodePlugin: Plugin = {\n name: 'default',\n description: 'Default plugin, with basic actions and evaluators',\n services: [BrowserService, PdfService, VideoService, AwsS3Service],\n actions: [],\n};\n"],"mappings":"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","names":["path","require_src","create","args","Service","ServiceType","logger","Service","ServiceType","fs","path","ModelType","Service","ServiceType","logger","stringToUuid","ytdl"]}
|
package/package.json
CHANGED
|
@@ -1,58 +1,61 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
2
|
+
"name": "@elizaos/plugin-browser",
|
|
3
|
+
"version": "1.0.0-alpha.64",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/elizaos-plugins/plugin-browser"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
"./package.json": "./package.json",
|
|
14
|
+
".": {
|
|
15
|
+
"import": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"scripts",
|
|
24
|
+
"package.json",
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"tsup.config.ts"
|
|
27
|
+
],
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@aws-sdk/client-s3": "^3.705.0",
|
|
30
|
+
"@aws-sdk/s3-request-presigner": "^3.705.0",
|
|
31
|
+
"@elizaos/core": "^1.0.0-alpha.64",
|
|
32
|
+
"@types/uuid": "10.0.0",
|
|
33
|
+
"capsolver-npm": "2.0.2",
|
|
34
|
+
"fluent-ffmpeg": "2.1.3",
|
|
35
|
+
"glob": "11.0.0",
|
|
36
|
+
"patchright": "1.50.1",
|
|
37
|
+
"pdfjs-dist": "4.7.76",
|
|
38
|
+
"uuid": "11.0.3"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "22.8.4",
|
|
42
|
+
"prettier": "3.5.3",
|
|
43
|
+
"tsup": "8.4.0"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsup",
|
|
47
|
+
"dev": "tsup --watch",
|
|
48
|
+
"postinstall": "node scripts/postinstall.js",
|
|
49
|
+
"lint": "prettier --write ./src",
|
|
50
|
+
"clean": "rm -rf dist .turbo node_modules .turbo-tsconfig.json tsconfig.tsbuildinfo",
|
|
51
|
+
"format": "prettier --write ./src",
|
|
52
|
+
"format:check": "prettier --check ./src"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"whatwg-url": "7.1.0"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
},
|
|
60
|
+
"gitHead": "be3a1856c64c6d1ae2ec73e9f35b83ef827b0c55"
|
|
58
61
|
}
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,70 +1,67 @@
|
|
|
1
|
-
import { execSync } from
|
|
2
|
-
import fs from
|
|
3
|
-
import os from
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
4
|
|
|
5
5
|
const platform = os.platform();
|
|
6
6
|
const rel = os.release();
|
|
7
7
|
|
|
8
|
-
if (platform !==
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
platform,
|
|
12
|
-
);
|
|
13
|
-
process.exit(0);
|
|
8
|
+
if (platform !== 'linux') {
|
|
9
|
+
console.log('Skipping [patchright] installation: non-Linux platform detected:', platform);
|
|
10
|
+
process.exit(0);
|
|
14
11
|
}
|
|
15
12
|
|
|
16
13
|
function getDistroName() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
try {
|
|
15
|
+
const osReleaseContent = fs.readFileSync('/etc/os-release', 'utf8');
|
|
16
|
+
const lines = osReleaseContent.split('\n');
|
|
17
|
+
const info = {};
|
|
18
|
+
for (const line of lines) {
|
|
19
|
+
const [key, value] = line.split('=');
|
|
20
|
+
if (key && value) {
|
|
21
|
+
info[key.toLowerCase()] = value.replace(/"/g, '').toLowerCase().trim();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return info.id || info.id_like || null;
|
|
25
|
+
} catch (err) {
|
|
26
|
+
console.error('Error reading /etc/os-release:', err.message);
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
32
29
|
}
|
|
33
30
|
|
|
34
31
|
const distro = getDistroName();
|
|
35
|
-
console.log(
|
|
32
|
+
console.log('Detected Linux distribution:', distro || 'unknown');
|
|
36
33
|
|
|
37
34
|
const supportedDistros = [
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
35
|
+
'ubuntu',
|
|
36
|
+
'debian',
|
|
37
|
+
'pve',
|
|
38
|
+
'raspbian',
|
|
39
|
+
'pop',
|
|
40
|
+
'zorin',
|
|
41
|
+
'linuxmint',
|
|
42
|
+
'elementary',
|
|
43
|
+
'pureos',
|
|
44
|
+
'kali',
|
|
48
45
|
];
|
|
49
46
|
|
|
50
47
|
if (!distro || !supportedDistros.some((name) => distro.includes(name))) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
console.log(
|
|
49
|
+
'Skipping [patchright] installation on unsupported platform:',
|
|
50
|
+
platform,
|
|
51
|
+
rel,
|
|
52
|
+
distro || 'unknown distro'
|
|
53
|
+
);
|
|
54
|
+
process.exit(0);
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
try {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
execSync('npx patchright install', {
|
|
59
|
+
stdio: 'inherit',
|
|
60
|
+
});
|
|
64
61
|
} catch (err) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
62
|
+
console.error(
|
|
63
|
+
"Failed to install [patchright] you may need to install [patchright] deps with 'sudo npx patchright install-deps'. Error: ",
|
|
64
|
+
err.message
|
|
65
|
+
);
|
|
66
|
+
process.exit(1);
|
|
70
67
|
}
|
package/tsup.config.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { defineConfig } from
|
|
1
|
+
import { defineConfig } from 'tsup';
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
4
|
+
entry: ['src/index.ts'],
|
|
5
|
+
outDir: 'dist',
|
|
6
|
+
tsconfig: './tsconfig.build.json', // Use build-specific tsconfig
|
|
7
|
+
sourcemap: true,
|
|
8
|
+
clean: true,
|
|
9
|
+
format: ['esm'], // Ensure you're targeting CommonJS
|
|
10
|
+
dts: false, // Skip DTS generation to avoid external import issues // Ensure you're targeting CommonJS
|
|
11
|
+
external: [
|
|
12
|
+
'dotenv', // Externalize dotenv to prevent bundling
|
|
13
|
+
'fs', // Externalize fs to use Node.js built-in module
|
|
14
|
+
'path', // Externalize other built-ins if necessary
|
|
15
|
+
'@reflink/reflink',
|
|
16
|
+
'https',
|
|
17
|
+
'http',
|
|
18
|
+
'agentkeepalive',
|
|
19
|
+
'zod',
|
|
20
|
+
'@elizaos/core',
|
|
21
|
+
// Add other modules you want to externalize
|
|
22
|
+
],
|
|
23
23
|
});
|