-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add YouTube video caption tool and related stories/tests #149
Changes from 1 commit
312df5b
12aeba7
35fe36f
361dd21
fcea8e0
85ac1cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './firecrawl/index.js'; | ||
export * from './tavily/index.js'; | ||
export * from './youtube-video-caption/index.js'; | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { Tool } from '@langchain/core/tools'; | ||
import { z } from 'zod'; | ||
import ky from 'ky'; | ||
import { HTTPError } from 'ky'; | ||
import { getSubtitles } from 'youtube-captions-scraper'; | ||
|
||
export class YouTubeVideoCaption extends Tool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is best to call the tool: youtube-captions-scraper |
||
constructor(fields) { | ||
super(fields); | ||
this.token = fields.token; | ||
this.name = 'youtube_video_caption'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is better to call the tool: youtube-captions-scraper |
||
this.description = 'Tools to extract video caption from youtube'; | ||
this.httpClient = ky; | ||
|
||
// Define the input schema using Zod | ||
this.schema = z.object({ | ||
videoId: z | ||
.string() | ||
.describe('The ID of the YouTube video to extract captions from.'), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use the Youtube url instead of the video id. |
||
}); | ||
} | ||
|
||
async _call(input) { | ||
try { | ||
const headers = { | ||
Authorization: `Bearer ${this.token}`, | ||
}; | ||
// Make an API request to the YouTube Data API | ||
|
||
const jsonData = await this.httpClient | ||
.get( | ||
`https://www.googleapis.com/youtube/v3/captions?videoId=${input.videoId}&part=id,snippet`, | ||
{ headers } | ||
) | ||
.json(); | ||
// Extract and validate the results from the response | ||
const captions = jsonData?.items[0]?.snippet; | ||
if (!captions) { | ||
return 'No captions found'; | ||
} | ||
const captionContent = await downloadAutoGeneratedCaptions( | ||
input.videoId, | ||
captions.language | ||
); | ||
|
||
return captionContent; | ||
} catch (error) { | ||
if (error instanceof HTTPError) { | ||
const statusCode = error.response.status; | ||
let errorType = 'Unknown'; | ||
if (statusCode >= 400 && statusCode < 500) { | ||
errorType = 'Client Error'; | ||
} else if (statusCode >= 500) { | ||
errorType = 'Server Error'; | ||
} | ||
return `API request failed: ${errorType} (${statusCode})`; | ||
} else { | ||
return `An unexpected error occurred: ${error.message}`; | ||
} | ||
} | ||
} | ||
} | ||
|
||
const downloadAutoGeneratedCaptions = async (videoId, lang = 'en') => { | ||
try { | ||
const captions = await getSubtitles({ | ||
videoID: videoId, // YouTube video ID | ||
lang, // Language code for captions, change as neededd | ||
}); | ||
|
||
// Process and display the captions | ||
let captionContent = `Video Id: ${videoId}\n\n`; | ||
|
||
for (let index = 0; index < captions.length; index++) { | ||
const caption = captions[index]; | ||
captionContent += `[${caption.start}]: ${caption.text}\n`; | ||
} | ||
|
||
return captionContent; | ||
} catch (error) { | ||
console.error('Error downloading captions:', error); | ||
} | ||
}; |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LEt's use for the name of the file tool.stories.jsx |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { ToolPreviewer } from '../_utils/ToolPreviewer.jsx'; | ||
import { YouTubeVideoCaption } from './index.js'; | ||
import { Agent, Task, Team } from '../../../../src/index'; | ||
import React from 'react'; | ||
import { AgentWithToolPreviewer } from '../_utils/AgentWithToolPreviewer.jsx'; | ||
|
||
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export | ||
export default { | ||
title: 'Tools/YouTube', | ||
component: ToolPreviewer, | ||
parameters: { | ||
layout: 'centered', | ||
}, | ||
tags: ['autodocs'], | ||
}; | ||
|
||
const youtubeTool = new YouTubeVideoCaption({ | ||
token: import.meta.env.VITE_YOUTUBE_LONG_LIVE_TOKEN, | ||
}); | ||
|
||
// Create an agent with the YouTube tool | ||
const captionExtractor = new Agent({ | ||
name: 'Caption Extractor', | ||
role: 'YouTube Caption Analyzer', | ||
goal: 'Extract and analyze captions from YouTube videos', | ||
tools: [youtubeTool], | ||
maxIterations: 5, | ||
}); | ||
|
||
// Create a caption extraction task | ||
const captionExtractionTask = new Task({ | ||
description: | ||
'Extract captions for video ID: {videoId} and provide a structured summary', | ||
agent: captionExtractor, | ||
expectedOutput: 'A well-formatted analysis of the video captions', | ||
}); | ||
|
||
// Create the team | ||
const team = new Team({ | ||
name: 'Caption Extraction Unit', | ||
description: | ||
'Specialized team for extracting and analyzing YouTube video captions', | ||
agents: [captionExtractor], | ||
tasks: [captionExtractionTask], | ||
inputs: { | ||
videoId: 'NFpqFEl-URY', // Example video ID | ||
}, | ||
env: { | ||
OPENAI_API_KEY: import.meta.env.VITE_OPENAI_API_KEY, | ||
}, | ||
}); | ||
|
||
export const Default = { | ||
args: { | ||
toolInstance: youtubeTool, | ||
callParams: { | ||
videoId: 'NFpqFEl-URY', | ||
}, | ||
}, | ||
}; | ||
|
||
export const withAgent = { | ||
render: (args) => <AgentWithToolPreviewer {...args} />, | ||
args: { | ||
team: team, | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is best to call the tool: youtube-captions-scraper