@triplef/agent 0.1.5 → 0.1.6

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.
@@ -518,7 +518,7 @@ function extractYoutubeVideoId(url) {
518
518
  }
519
519
  function buildYoutubeThumbnailUrl(url) {
520
520
  const id = extractYoutubeVideoId(url);
521
- return id ? `https://i.ytimg.com/vi/${id}/hqdefault.jpg` : void 0;
521
+ return id ? `https://i.ytimg.com/vi/${id}/maxresdefault.jpg` : void 0;
522
522
  }
523
523
 
524
524
  // src/tools/helpers/localized-query-suffix.helper.ts
@@ -1314,6 +1314,22 @@ var serperVideoSearchSchema = z.object({
1314
1314
  recency: z.enum(["day", "week", "month", "year"]).optional().describe(RECENCY_DESCRIPTION),
1315
1315
  lang: z.string().optional().describe("Two-letter ISO language code for result preference (e.g. en, de, ja)")
1316
1316
  });
1317
+
1318
+ // src/tools/helpers/repair-video-link.helper.ts
1319
+ var YOUTUBE_LINK_PATTERN = /^https?:\/\/(?:[a-z0-9-]+\.)*youtube\.com\/(?:watch\?v=|shorts\/|embed\/|live\/|v\/|e\/)([A-Za-z0-9_-]{11})(?![A-Za-z0-9_-])/;
1320
+ var YOUTU_BE_LINK_PATTERN = /^https?:\/\/youtu\.be\/([A-Za-z0-9_-]{11})(?![A-Za-z0-9_-])/;
1321
+ var YOUTUBE_NOCOOKIE_LINK_PATTERN = /^https?:\/\/(?:www\.)?youtube-nocookie\.com\/(?:embed\/|v\/)([A-Za-z0-9_-]{11})(?![A-Za-z0-9_-])/;
1322
+ var YOUTUBE_HOST_PATTERN = /^https?:\/\/(?:[a-z0-9-]+\.)*youtube(?:-nocookie)?\.com\/|^https?:\/\/youtu\.be\//;
1323
+ var CONTAMINATION_PATTERN = /[\s"'<>\uFFFD]/;
1324
+ function repairVideoLink(link) {
1325
+ if (!link) return void 0;
1326
+ const id = YOUTUBE_LINK_PATTERN.exec(link)?.[1] ?? YOUTU_BE_LINK_PATTERN.exec(link)?.[1] ?? YOUTUBE_NOCOOKIE_LINK_PATTERN.exec(link)?.[1];
1327
+ if (id) return `https://www.youtube.com/watch?v=${id}`;
1328
+ if (YOUTUBE_HOST_PATTERN.test(link)) return void 0;
1329
+ return CONTAMINATION_PATTERN.test(link) ? void 0 : link;
1330
+ }
1331
+
1332
+ // src/tools/serper/video-search.tool.ts
1317
1333
  function createSerperVideoSearch(deps) {
1318
1334
  return tool({
1319
1335
  description: 'Search for videos using Serper.dev. Returns titles, links, channel names, duration, and publish dates. Only return URLs from supported embeddable providers: YouTube, Vimeo, Dailymotion, Loom, Wistia, or direct video files. Reject Instagram, Facebook, TikTok, Twitch, X/Twitter, and other unreliable platforms. Pass recency ("day"|"week"|"month"|"year") to restrict to recently uploaded videos. ' + STANDALONE_QUERY_TOOL_CLAUSE,
@@ -1345,16 +1361,24 @@ function createSerperVideoSearch(deps) {
1345
1361
  if (!res.ok) return { results: [] };
1346
1362
  const data = await res.json();
1347
1363
  if (!data.videos?.length) return { results: [] };
1348
- const results = data.videos.slice(0, num).map((r) => ({
1364
+ const results = data.videos.flatMap((r) => {
1365
+ const link = repairVideoLink(r.link);
1366
+ return link ? [{ r, link }] : [];
1367
+ }).slice(0, num).map(({ r, link }) => ({
1349
1368
  title: r.title,
1350
- link: r.link,
1369
+ link,
1370
+ // Keep the provider's original link when it had to be repaired —
1371
+ // auditability for provider-side payload corruption.
1372
+ ...link !== r.link ? { originalLink: r.link } : {},
1351
1373
  snippet: r.snippet || "",
1352
1374
  channel: r.channel || "",
1353
1375
  duration: r.duration || "",
1354
1376
  date: r.date || "",
1355
1377
  // Serper thumbnails are Google proxy images (blocked by our image
1356
1378
  // trust rules) — derive a direct thumbnail for YouTube instead.
1357
- thumbnailUrl: buildYoutubeThumbnailUrl(r.link) ?? "",
1379
+ // maxresdefault is not guaranteed to exist; consumers degrade to
1380
+ // hqdefault/mqdefault on failure.
1381
+ thumbnailUrl: buildYoutubeThumbnailUrl(link) ?? "",
1358
1382
  source: r.source || "",
1359
1383
  views: r.views ?? 0
1360
1384
  }));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@triplef/agent",
3
3
  "description": "tripleF (3F) agent domain — structured-output schemas, prompt builders, and model tools shared across the apps.",
4
- "version": "0.1.5",
4
+ "version": "0.1.6",
5
5
  "packageManager": "pnpm@11.24.0",
6
6
  "license": "MIT",
7
7
  "type": "module",