Skip to content

Commit

Permalink
- feature: added youtube transcript tool
Browse files Browse the repository at this point in the history
  • Loading branch information
agallardol committed Sep 4, 2024
1 parent 6ea96d2 commit 4d7446a
Show file tree
Hide file tree
Showing 12 changed files with 337 additions and 107 deletions.
6 changes: 6 additions & 0 deletions apps/shinkai-tool-youtube-transcript/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-disable */
export default {
displayName: '@shinkai_protocol/shinkai-tool-youtube-transcript',
preset: '../../jest.preset.js',
coverageDirectory: '../../coverage/apps/shinkai-tool-youtube-transcript',
};
4 changes: 4 additions & 0 deletions apps/shinkai-tool-youtube-transcript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@shinkai_protocol/shinkai-tool-youtube-transcript",
"type": "commonjs"
}
30 changes: 30 additions & 0 deletions apps/shinkai-tool-youtube-transcript/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "@shinkai_protocol/shinkai-tool-youtube-transcript",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/shinkai-tool-youtube-transcript/src",
"projectType": "library",
"tags": ["tool"],
"targets": {
"build": {
"executor": "nx:run-commands",
"defaultConfiguration": "production",
"options": {
"command": "npx ts-node scripts/tool-bundler.ts --entry ./apps/shinkai-tool-youtube-transcript/src/index.ts --outputFolder ./dist/apps/shinkai-tool-youtube-transcript"
},
"configurations": {
"development": {},
"production": {}
}
},
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": [
"apps/shinkai-tool-youtube-transcript/**/*.ts",
"apps/shinkai-tool-youtube-transcript/package.json"
]
}
}
}
}
20 changes: 20 additions & 0 deletions apps/shinkai-tool-youtube-transcript/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Tool } from '../src/index';

test('exists definition', async () => {
const tool = new Tool({});
const definition = tool.getDefinition();
expect(definition).toBeInstanceOf(Object);
});

test('transcript video', async () => {
const tool = new Tool({});
const result = await tool.run({
// Video about Shinkai Sheets
url: 'https://youtu.be/RxxuM4wbVQc',
ollamaModel: 'llama3.1:8b-instruct-q4_1'
});
expect(result.data.transcript).toBeInstanceOf(Array);
expect(result.data.transcript.length).toBeGreaterThan(0);

console.log(result.data.message);
}, 30000);
105 changes: 105 additions & 0 deletions apps/shinkai-tool-youtube-transcript/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { BaseTool, RunResult } from '@shinkai_protocol/shinkai-tools-builder';
import { ToolDefinition } from 'libs/shinkai-tools-builder/src/tool-definition';
import { TranscriptResponse, YoutubeTranscript } from 'youtube-transcript';
import { Ollama } from 'ollama';

type Config = {
ollamaApiUrl?: string;
};
type Params = {
url: string;
ollamaModel: string;
};
type Result = { transcript: TranscriptResponse[]; message: string };

export class Tool extends BaseTool<Config, Params, Result> {
definition: ToolDefinition<Config, Params, Result> = {
id: 'shinkai-tool-youtube-transcript',
name: 'Shinkai: YouTube Transcript',
description: 'Retrieve the transcript of a YouTube video',
author: 'Shinkai',
keywords: ['youtube', 'transcript', 'video', 'captions', 'subtitles'],
configurations: {
type: 'object',
properties: {
ollamaApiUrl: { type: 'string', nullable: true },
},
required: [],
},
parameters: {
type: 'object',
properties: {
url: {
type: 'string',
description: 'The URL of the YouTube video to transcribe',
},
ollamaModel: {
type: 'string',
description: 'The Ollama model to use for generating the summary',
},
},
required: ['url'],
},
result: {
type: 'object',
properties: {
transcript: {
type: 'array',
items: {
type: 'object',
properties: {
text: { type: 'string' },
duration: { type: 'number' },
offset: { type: 'number' },
lang: { type: 'string', nullable: true },
},
required: ['text', 'duration', 'offset'],
},
},
message: { type: 'string' },
},
required: ['transcript'],
},
};

async run(params: Params): Promise<RunResult<Result>> {
console.log(`transcripting ${params.url}`);

// Get transcription
const transcript = await YoutubeTranscript.fetchTranscript(params.url);

// Send to ollama to build a formatted response
const message = {
role: 'user',
content: `
According to this transcription of a youtube video (which is in csv separated by ';'):
offset;text
${transcript.map((v) => `${v.offset};${v.text}`).join('\n')}
---------------
The video URL is ${params.url}
---------------
Write a detailed summary divided in sections along the video.
Format the answer using markdown.
Add markdown links referencing every section using this format https://www.youtube.com/watch?v={video_id}&t={offset} where 'offset' is a number and can be obtained from the transcription in csv format and should be in seconds to generate the URL
`,
};
const ollamaClient = new Ollama({ host: 'http://localhost:11435' });
try {
const response = await ollamaClient.chat({
model: params.ollamaModel,
messages: [message],
stream: false,
});
return Promise.resolve({
data: { transcript, message: response.message.content },
});
} catch (error) {
console.error('Error calling Ollama API:', error);
throw error;
}
}
}
4 changes: 4 additions & 0 deletions apps/shinkai-tool-youtube-transcript/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"include": ["./src/**/*.ts"]
}
10 changes: 10 additions & 0 deletions apps/shinkai-tool-youtube-transcript/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {

},
"include": [
"./src/**/*.ts",
"webpack.config.ts"
],
}
14 changes: 14 additions & 0 deletions apps/shinkai-tool-youtube-transcript/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
158 changes: 84 additions & 74 deletions libs/shinkai-tools-runner/src/built_in_tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ lazy_static! {
.unwrap(),
)),
);
// https://bugzilla.mozilla.org/show_bug.cgi?id=1681809
// https://bugzilla.mozilla.org/show_bug.cgi?id=1681809
m.insert(
"shinkai-tool-token-price",
&*Box::leak(Box::new(
Expand All @@ -106,17 +106,17 @@ lazy_static! {
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-duckduckgo-search",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-duckduckgo-search/definition.json"
)))
.unwrap(),
)),
);
);
m.insert(
"shinkai-tool-duckduckgo-search",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-duckduckgo-search/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-playwright-example",
&*Box::leak(Box::new(
Expand All @@ -138,75 +138,85 @@ lazy_static! {
)),
);
m.insert(
"shinkai-tool-aave-loan-requester",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-aave-loan-requester/definition.json"
)))
.unwrap(),
"shinkai-tool-aave-loan-requester",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-aave-loan-requester/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-call-faucet",
);
m.insert(
"shinkai-tool-coinbase-call-faucet",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-call-faucet/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-create-wallet",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-create-wallet/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-get-balance",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-get-balance/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-send-tx",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-send-tx/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-get-transactions",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-get-transactions/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-get-my-address",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-call-faucet/definition.json"
"/tools/shinkai-tool-coinbase-get-my-address/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-create-wallet",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-create-wallet/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-get-balance",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-get-balance/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-send-tx",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-send-tx/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-get-transactions",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-get-transactions/definition.json"
)))
.unwrap(),
)),
);
m.insert(
"shinkai-tool-coinbase-get-my-address",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-coinbase-get-my-address/definition.json"
)))
.unwrap(),
)),
);
);
m.insert(
"shinkai-tool-youtube-transcript",
&*Box::leak(Box::new(
serde_json::from_str::<ToolDefinition>(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tools/shinkai-tool-youtube-transcript/definition.json"
)))
.unwrap(),
)),
);
// ntim: New tools will be inserted here, don't remove this comment
m
};
Expand Down
Loading

0 comments on commit 4d7446a

Please sign in to comment.