From 6bf96cc2523d1b3d806cc919d4da83a07acc27d6 Mon Sep 17 00:00:00 2001 From: maanethdesilva Date: Fri, 24 Nov 2023 00:39:02 -0500 Subject: [PATCH 1/2] Added the discord get messages tool. --- langchain/package.json | 1 + langchain/src/tools/discord.ts | 70 +++++++ langchain/src/tools/tests/discord.test.ts | 12 ++ yarn.lock | 213 +++++++++++++++++++++- 4 files changed, 287 insertions(+), 9 deletions(-) create mode 100644 langchain/src/tools/discord.ts create mode 100644 langchain/src/tools/tests/discord.test.ts diff --git a/langchain/package.json b/langchain/package.json index 628381783036..3b3a512eeb73 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -1384,6 +1384,7 @@ "@langchain/core": "^0.0.1", "@langchain/openai": "^0.0.1", "binary-extensions": "^2.2.0", + "discord.js": "^14.14.1", "expr-eval": "^2.0.2", "flat": "^5.0.2", "js-tiktoken": "^1.0.7", diff --git a/langchain/src/tools/discord.ts b/langchain/src/tools/discord.ts new file mode 100644 index 000000000000..31336b6bc3b1 --- /dev/null +++ b/langchain/src/tools/discord.ts @@ -0,0 +1,70 @@ +import { getEnvironmentVariable } from "../util/env.js"; +import { Tool } from "./base.js"; +import { Client, TextChannel, GatewayIntentBits, Message } from "discord.js"; + +/* + * A tool for retrieving messages from a discord channel using a bot. + * It extends the base Tool class and implements the _call method to + * perform the retrieve operation. Requires an bot token which can be set + * in the environment variables, and a limit on how many messages to retrieve. + * The _call method takes the discord channel ID as the input argument. + * The bot must have read permissions to the given channel. It returns the + * message content, author, and time the message was created for each message. + */ + +export class DiscordGetMessagesTool extends Tool { + static lc_name() { + return "DiscordGetMessagesTool"; + } + + name = "discord-get-messages"; + + description = `a discord tool. useful for reading messages from a discord channel. + input should be the discord channel ID. the bot should have read + permissions for the channel`; + + protected botToken: string; + protected messageLimit: number; + + client = new Client({ + intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], + }); + + constructor( + botToken: string | undefined = getEnvironmentVariable("DiscordBotToken"), + messageLimit: number | undefined = 100 + ) { + super(...arguments); + + if (!botToken) { + throw new Error( + "Discord API key not set. You can set it as DiscordBotToken in your .env file." + ); + } + + this.botToken = botToken; + this.messageLimit = messageLimit; + } + + /** @ignore */ + async _call(input: string): Promise { + await this.client.login(this.botToken); + + const channel = (await this.client.channels.fetch(input)) as TextChannel; + + if (!channel) { + return "Channel not found"; + } + + const messages = await channel.messages.fetch({ limit: this.messageLimit }); + this.client.destroy(); + const results = + messages.map((message: Message) => ({ + author: message.author.tag, + content: message.content, + timestamp: message.createdAt, + })) ?? []; + + return JSON.stringify(results); + } +} diff --git a/langchain/src/tools/tests/discord.test.ts b/langchain/src/tools/tests/discord.test.ts new file mode 100644 index 000000000000..981c94c86c41 --- /dev/null +++ b/langchain/src/tools/tests/discord.test.ts @@ -0,0 +1,12 @@ +import { test } from "@jest/globals"; +import { DiscordGetMessagesTool } from "../discord.js"; + +test("DiscordGetMessagesTool", async () => { + const tool = new DiscordGetMessagesTool(); + try { + const result = await tool.call('1153400523718938780') + console.log(result) + } catch (error) { + console.error(error); + } +}); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index c4d7df0ebdf4..9ee670324266 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6010,6 +6010,85 @@ __metadata: languageName: node linkType: hard +"@discordjs/builders@npm:^1.7.0": + version: 1.7.0 + resolution: "@discordjs/builders@npm:1.7.0" + dependencies: + "@discordjs/formatters": ^0.3.3 + "@discordjs/util": ^1.0.2 + "@sapphire/shapeshift": ^3.9.3 + discord-api-types: 0.37.61 + fast-deep-equal: ^3.1.3 + ts-mixer: ^6.0.3 + tslib: ^2.6.2 + checksum: 837e7643fc8396e4914bbbfbbfa1232ab7109c931884e8df45cd7356944633590f710a18513d30a10de1b6686ed5166df702bde0c4511fb0cbcac897edd9e56a + languageName: node + linkType: hard + +"@discordjs/collection@npm:1.5.3": + version: 1.5.3 + resolution: "@discordjs/collection@npm:1.5.3" + checksum: fefed19bea0f69053d195f9d9dc8af07ca5d8c9b1064581e0aa14bda2b70e632b93c164d5ef3e4910f5442369612ff4eec8d52a700aec562510c19b223f67023 + languageName: node + linkType: hard + +"@discordjs/collection@npm:^2.0.0": + version: 2.0.0 + resolution: "@discordjs/collection@npm:2.0.0" + checksum: c2d05fa2b9a27bb64e93e2836bbe44c835d21f85e28cd934f6e2a81fef423ab0415968cca9d066b83347539edc8ea9afa8075d80bd62594e39f09eb881052c49 + languageName: node + linkType: hard + +"@discordjs/formatters@npm:^0.3.3": + version: 0.3.3 + resolution: "@discordjs/formatters@npm:0.3.3" + dependencies: + discord-api-types: 0.37.61 + checksum: a844628094a6effa8ac4e4a4ea9082d5c89e6cae6bbd18e60abd410769e5ea18f64aa2db8623aa3c8c572084368f6c2e27cc2d72af640aff5e4ee7fc42132c60 + languageName: node + linkType: hard + +"@discordjs/rest@npm:^2.1.0": + version: 2.2.0 + resolution: "@discordjs/rest@npm:2.2.0" + dependencies: + "@discordjs/collection": ^2.0.0 + "@discordjs/util": ^1.0.2 + "@sapphire/async-queue": ^1.5.0 + "@sapphire/snowflake": ^3.5.1 + "@vladfrangu/async_event_emitter": ^2.2.2 + discord-api-types: 0.37.61 + magic-bytes.js: ^1.5.0 + tslib: ^2.6.2 + undici: 5.27.2 + checksum: 29a14ecf3282ae3306883f1f6c870693d0ecacd080c5b66a72e31487a8070655807a80a8bf09bebea4f73e631439abc5121dfa38016ca0ccbe3f68c0f7ffc80e + languageName: node + linkType: hard + +"@discordjs/util@npm:^1.0.2": + version: 1.0.2 + resolution: "@discordjs/util@npm:1.0.2" + checksum: 320d7e125981001160d413ae56e76e60447dce102010b80e3b1b16d885be765df5ae2551aa79fdc4d435a82361ed72246b44251f0c1f7a8fef7056a4481d5609 + languageName: node + linkType: hard + +"@discordjs/ws@npm:^1.0.2": + version: 1.0.2 + resolution: "@discordjs/ws@npm:1.0.2" + dependencies: + "@discordjs/collection": ^2.0.0 + "@discordjs/rest": ^2.1.0 + "@discordjs/util": ^1.0.2 + "@sapphire/async-queue": ^1.5.0 + "@types/ws": ^8.5.9 + "@vladfrangu/async_event_emitter": ^2.2.2 + discord-api-types: 0.37.61 + tslib: ^2.6.2 + ws: ^8.14.2 + checksum: 2564d3ff00d04d7638955c8c9a9f6234c50168fbe8243140bc458dc9ffa39ad5063e7d5762cdce71bb8bcf70b6353c28b8531e40f54568706898e92bc8748590 + languageName: node + linkType: hard + "@discoveryjs/json-ext@npm:0.5.7": version: 0.5.7 resolution: "@discoveryjs/json-ext@npm:0.5.7" @@ -7071,6 +7150,13 @@ __metadata: languageName: node linkType: hard +"@fastify/busboy@npm:^2.0.0": + version: 2.1.0 + resolution: "@fastify/busboy@npm:2.1.0" + checksum: 3233abd10f73e50668cb4bb278a79b7b3fadd30215ac6458299b0e5a09a29c3586ec07597aae6bd93f5cbedfcef43a8aeea51829cd28fc13850cdbcd324c28d5 + languageName: node + linkType: hard + "@firebase/app-types@npm:0.9.0": version: 0.9.0 resolution: "@firebase/app-types@npm:0.9.0" @@ -9021,6 +9107,30 @@ __metadata: languageName: node linkType: hard +"@sapphire/async-queue@npm:^1.5.0": + version: 1.5.0 + resolution: "@sapphire/async-queue@npm:1.5.0" + checksum: 983dbd1fd1b1798496e5edb6a0db7e4d90015160e1028f20475eab0a92625513f1e8d938bc0305811a9cec461c94e01b1e4191615ff03ba49356f568f3255250 + languageName: node + linkType: hard + +"@sapphire/shapeshift@npm:^3.9.3": + version: 3.9.3 + resolution: "@sapphire/shapeshift@npm:3.9.3" + dependencies: + fast-deep-equal: ^3.1.3 + lodash: ^4.17.21 + checksum: f93ab924566dc20a066776128eeb3693b97a1576a359b61d396835541f2bf8ecb3f482ff406cc038a3a4bc266d5f9b9f9e1c733ddbf1cce2c97c729ce047b5e6 + languageName: node + linkType: hard + +"@sapphire/snowflake@npm:3.5.1, @sapphire/snowflake@npm:^3.5.1": + version: 3.5.1 + resolution: "@sapphire/snowflake@npm:3.5.1" + checksum: 8fc025020adab1a7a1a5d2cf07704d598cc1977b50e5fcd3a5dd239f00934dc936d3a4d5ae336e71d8bf1d88ec27aa814b34de79e38ff097b7b9ba5a7977a683 + languageName: node + linkType: hard + "@selderee/plugin-htmlparser2@npm:^0.11.0": version: 0.11.0 resolution: "@selderee/plugin-htmlparser2@npm:0.11.0" @@ -11961,6 +12071,15 @@ __metadata: languageName: node linkType: hard +"@types/ws@npm:8.5.9": + version: 8.5.9 + resolution: "@types/ws@npm:8.5.9" + dependencies: + "@types/node": "*" + checksum: 83f436b731d2cdc49a45ced31a0a65cdd2e39c24d7b882776c26efa190dad6553e266d624c7a7089f36ad3ed471e02e729f3219282c80689b435f665df4a2b0b + languageName: node + linkType: hard + "@types/ws@npm:^8": version: 8.5.8 resolution: "@types/ws@npm:8.5.8" @@ -11979,6 +12098,15 @@ __metadata: languageName: node linkType: hard +"@types/ws@npm:^8.5.9": + version: 8.5.10 + resolution: "@types/ws@npm:8.5.10" + dependencies: + "@types/node": "*" + checksum: 3ec416ea2be24042ebd677932a462cf16d2080393d8d7d0b1b3f5d6eaa4a7387aaf0eefb99193c0bfd29444857cf2e0c3ac89899e130550dc6c14ada8a46d25e + languageName: node + linkType: hard + "@types/yargs-parser@npm:*": version: 21.0.0 resolution: "@types/yargs-parser@npm:21.0.0" @@ -12364,6 +12492,13 @@ __metadata: languageName: node linkType: hard +"@vladfrangu/async_event_emitter@npm:^2.2.2": + version: 2.2.2 + resolution: "@vladfrangu/async_event_emitter@npm:2.2.2" + checksum: ed948294fea1a2dc8b8f307f4061bf65e2043a946132f288702f0572a806ebe3123b8c7e522e70d2abbd3616f5d67027c9e59df9ef80b0195f7502a848a426ba + languageName: node + linkType: hard + "@webassemblyjs/ast@npm:1.11.6, @webassemblyjs/ast@npm:^1.11.5": version: 1.11.6 resolution: "@webassemblyjs/ast@npm:1.11.6" @@ -16119,6 +16254,35 @@ __metadata: languageName: node linkType: hard +"discord-api-types@npm:0.37.61": + version: 0.37.61 + resolution: "discord-api-types@npm:0.37.61" + checksum: fe33d528e31a6de0bab2afb43d0e058957a6da6cfc4d797943fac83aeb8d07543dc0f85cad3c4e6789cbbac0c7ca49dae5ac465224b129c7acb716097fa0b081 + languageName: node + linkType: hard + +"discord.js@npm:^14.14.1": + version: 14.14.1 + resolution: "discord.js@npm:14.14.1" + dependencies: + "@discordjs/builders": ^1.7.0 + "@discordjs/collection": 1.5.3 + "@discordjs/formatters": ^0.3.3 + "@discordjs/rest": ^2.1.0 + "@discordjs/util": ^1.0.2 + "@discordjs/ws": ^1.0.2 + "@sapphire/snowflake": 3.5.1 + "@types/ws": 8.5.9 + discord-api-types: 0.37.61 + fast-deep-equal: 3.1.3 + lodash.snakecase: 4.1.1 + tslib: 2.6.2 + undici: 5.27.2 + ws: 8.14.2 + checksum: 651e61861ae33e6ec3903e72a8bf229caae5dab73f8d409c3673430cafd9c438a0dd59983242bdcff47bab50da39f7a04da5b586c35b396c102e8e87637076e5 + languageName: node + linkType: hard + "dlv@npm:^1.1.3": version: 1.1.3 resolution: "dlv@npm:1.1.3" @@ -18045,7 +18209,7 @@ __metadata: languageName: node linkType: hard -"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": +"fast-deep-equal@npm:3.1.3, fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" checksum: e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d @@ -22374,6 +22538,7 @@ __metadata: cohere-ai: ">=6.0.0" convex: ^1.3.1 d3-dsv: ^2.0.0 + discord.js: ^14.14.1 dotenv: ^16.0.3 dpdm: ^3.12.0 epub2: ^3.0.1 @@ -23162,6 +23327,13 @@ __metadata: languageName: node linkType: hard +"lodash.snakecase@npm:4.1.1": + version: 4.1.1 + resolution: "lodash.snakecase@npm:4.1.1" + checksum: 1685ed3e83dda6eae5a4dcaee161a51cd210aabb3e1c09c57150e7dd8feda19e4ca0d27d0631eabe8d0f4eaa51e376da64e8c018ae5415417c5890d42feb72a8 + languageName: node + linkType: hard + "lodash.uniq@npm:4.5.0, lodash.uniq@npm:^4.5.0": version: 4.5.0 resolution: "lodash.uniq@npm:4.5.0" @@ -23398,6 +23570,13 @@ __metadata: languageName: node linkType: hard +"magic-bytes.js@npm:^1.5.0": + version: 1.5.0 + resolution: "magic-bytes.js@npm:1.5.0" + checksum: 058c58344b2030f1e76c6209110a0f3056179237ebb501c314793cdeb449fb588f081b4569a2784d3264ee0fc56b0b9dc3c9d9c46eb2c629e3866f03a6f18846 + languageName: node + linkType: hard + "magic-string@npm:^0.30.0": version: 0.30.3 resolution: "magic-string@npm:0.30.3" @@ -30022,6 +30201,13 @@ __metadata: languageName: node linkType: hard +"ts-mixer@npm:^6.0.3": + version: 6.0.3 + resolution: "ts-mixer@npm:6.0.3" + checksum: 7fbaba0a413bf817835a6a23d46bccf4192dd4d7345b6bae9d594c88acffac35bf4995ef3cce753090c8abcdf2afd16dba8899365584a1f960ccc2a15bf2e2d6 + languageName: node + linkType: hard + "ts-morph@npm:^20.0.0": version: 20.0.0 resolution: "ts-morph@npm:20.0.0" @@ -30057,6 +30243,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:2.6.2, tslib@npm:^2.0.3, tslib@npm:^2.6.2": + version: 2.6.2 + resolution: "tslib@npm:2.6.2" + checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad + languageName: node + linkType: hard + "tslib@npm:>=2, tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.5.0": version: 2.5.0 resolution: "tslib@npm:2.5.0" @@ -30071,13 +30264,6 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.3": - version: 2.6.2 - resolution: "tslib@npm:2.6.2" - checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad - languageName: node - linkType: hard - "tslib@npm:^2.2.0": version: 2.6.0 resolution: "tslib@npm:2.6.0" @@ -30670,6 +30856,15 @@ __metadata: languageName: node linkType: hard +"undici@npm:5.27.2": + version: 5.27.2 + resolution: "undici@npm:5.27.2" + dependencies: + "@fastify/busboy": ^2.0.0 + checksum: 22bbdd763798700979986546d70072b67223189353d2a811efa9c6e44476161a0d1781ffe24115221f69a1b344b95d5926bd39a6eb760a2cd8804781cec0c5eb + languageName: node + linkType: hard + "undici@npm:^5.19.1": version: 5.23.0 resolution: "undici@npm:5.23.0" @@ -31989,7 +32184,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.14.2": +"ws@npm:8.14.2, ws@npm:^8.14.2": version: 8.14.2 resolution: "ws@npm:8.14.2" peerDependencies: From ec6c255c0196589efc6ec96241a709f29bddcb63 Mon Sep 17 00:00:00 2001 From: maanethdesilva Date: Fri, 24 Nov 2023 14:59:28 -0500 Subject: [PATCH 2/2] Updated discord.js dependency --- docs/api_refs/typedoc.json | 1 + langchain/.gitignore | 3 +++ langchain/package.json | 14 +++++++++++++- langchain/scripts/create-entrypoints.js | 2 ++ langchain/src/load/import_constants.ts | 1 + langchain/src/load/import_type.d.ts | 3 +++ yarn.lock | 3 +++ 7 files changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/api_refs/typedoc.json b/docs/api_refs/typedoc.json index af9ad580acb2..f3bc2d93a19a 100644 --- a/docs/api_refs/typedoc.json +++ b/docs/api_refs/typedoc.json @@ -38,6 +38,7 @@ "./langchain/src/tools/aws_lambda.ts", "./langchain/src/tools/aws_sfn.ts", "./langchain/src/tools/calculator.ts", + "./langchain/src/tools/discord.ts", "./langchain/src/tools/render.ts", "./langchain/src/tools/sql.ts", "./langchain/src/tools/webbrowser.ts", diff --git a/langchain/.gitignore b/langchain/.gitignore index 85fbbed282c4..960b3249091a 100644 --- a/langchain/.gitignore +++ b/langchain/.gitignore @@ -58,6 +58,9 @@ tools/aws_sfn.d.ts tools/calculator.cjs tools/calculator.js tools/calculator.d.ts +tools/discord.cjs +tools/discord.js +tools/discord.d.ts tools/render.cjs tools/render.js tools/render.d.ts diff --git a/langchain/package.json b/langchain/package.json index 3b3a512eeb73..e22bae3586f8 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -70,6 +70,9 @@ "tools/calculator.cjs", "tools/calculator.js", "tools/calculator.d.ts", + "tools/discord.cjs", + "tools/discord.js", + "tools/discord.d.ts", "tools/render.cjs", "tools/render.js", "tools/render.d.ts", @@ -923,6 +926,7 @@ "cohere-ai": ">=6.0.0", "convex": "^1.3.1", "d3-dsv": "^2.0.0", + "discord.js": "^14.14.1", "dotenv": "^16.0.3", "dpdm": "^3.12.0", "epub2": "^3.0.1", @@ -1041,6 +1045,7 @@ "cohere-ai": ">=6.0.0", "convex": "^1.3.1", "d3-dsv": "^2.0.0", + "discord.js": "^14.14.1", "epub2": "^3.0.1", "faiss-node": "^0.5.1", "fast-xml-parser": "^4.2.7", @@ -1255,6 +1260,9 @@ "d3-dsv": { "optional": true }, + "discord.js": { + "optional": true + }, "epub2": { "optional": true }, @@ -1384,7 +1392,6 @@ "@langchain/core": "^0.0.1", "@langchain/openai": "^0.0.1", "binary-extensions": "^2.2.0", - "discord.js": "^14.14.1", "expr-eval": "^2.0.2", "flat": "^5.0.2", "js-tiktoken": "^1.0.7", @@ -1518,6 +1525,11 @@ "import": "./tools/calculator.js", "require": "./tools/calculator.cjs" }, + "./tools/discord": { + "types": "./tools/discord.d.ts", + "import": "./tools/discord.js", + "require": "./tools/discord.cjs" + }, "./tools/render": { "types": "./tools/render.d.ts", "import": "./tools/render.js", diff --git a/langchain/scripts/create-entrypoints.js b/langchain/scripts/create-entrypoints.js index 84eb088356c6..c204933ce88c 100644 --- a/langchain/scripts/create-entrypoints.js +++ b/langchain/scripts/create-entrypoints.js @@ -32,6 +32,7 @@ const entrypoints = { "tools/aws_lambda": "tools/aws_lambda", "tools/aws_sfn": "tools/aws_sfn", "tools/calculator": "tools/calculator", + "tools/discord": "tools/discord", "tools/render": "tools/render", "tools/sql": "tools/sql", "tools/webbrowser": "tools/webbrowser", @@ -341,6 +342,7 @@ const requiresOptionalDependency = [ "tools/aws_lambda", "tools/aws_sfn", "tools/calculator", + "tools/discord", "tools/sql", "tools/webbrowser", "tools/google_calendar", diff --git a/langchain/src/load/import_constants.ts b/langchain/src/load/import_constants.ts index c98adf9c6451..95826a84408f 100644 --- a/langchain/src/load/import_constants.ts +++ b/langchain/src/load/import_constants.ts @@ -7,6 +7,7 @@ export const optionalImportEntrypoints = [ "langchain/tools/aws_lambda", "langchain/tools/aws_sfn", "langchain/tools/calculator", + "langchain/tools/discord", "langchain/tools/sql", "langchain/tools/webbrowser", "langchain/tools/google_calendar", diff --git a/langchain/src/load/import_type.d.ts b/langchain/src/load/import_type.d.ts index 23fa4c3304b6..ac4bc5e6e85c 100644 --- a/langchain/src/load/import_type.d.ts +++ b/langchain/src/load/import_type.d.ts @@ -19,6 +19,9 @@ export interface OptionalImportMap { "langchain/tools/calculator"?: | typeof import("../tools/calculator.js") | Promise; + "langchain/tools/discord"?: + | typeof import("../tools/discord.js") + | Promise; "langchain/tools/sql"?: | typeof import("../tools/sql.js") | Promise; diff --git a/yarn.lock b/yarn.lock index 9ee670324266..ddfc4fd7ea0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22670,6 +22670,7 @@ __metadata: cohere-ai: ">=6.0.0" convex: ^1.3.1 d3-dsv: ^2.0.0 + discord.js: ^14.14.1 epub2: ^3.0.1 faiss-node: ^0.5.1 fast-xml-parser: ^4.2.7 @@ -22826,6 +22827,8 @@ __metadata: optional: true d3-dsv: optional: true + discord.js: + optional: true epub2: optional: true faiss-node: