From 6bf96cc2523d1b3d806cc919d4da83a07acc27d6 Mon Sep 17 00:00:00 2001 From: maanethdesilva Date: Fri, 24 Nov 2023 00:39:02 -0500 Subject: [PATCH 01/18] 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 02/18] 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: From 7c3859e5d8f301f87e6a17dc24a48311e9dcd789 Mon Sep 17 00:00:00 2001 From: your_username Date: Mon, 27 Nov 2023 17:05:04 -0500 Subject: [PATCH 03/18] Added send messages tool --- langchain/src/tools/discord.ts | 73 +++++++++++++++++++++++ langchain/src/tools/tests/discord.test.ts | 12 +++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/langchain/src/tools/discord.ts b/langchain/src/tools/discord.ts index 31336b6bc3b1..f104a2b6d89a 100644 --- a/langchain/src/tools/discord.ts +++ b/langchain/src/tools/discord.ts @@ -68,3 +68,76 @@ export class DiscordGetMessagesTool extends Tool { return JSON.stringify(results); } } + +/* + * A tool for sending messages to a discord channel using a bot. + * It extends the base Tool class and implements the _call method to + * perform the retrieve operation. Requires a bot token which can be set + * in the environment variables. The _call method takes the message to be + * sent as the input argument. + */ + +export class DiscordSendMessagesTool extends Tool { + static lc_name() { + return "DiscordSendMessagesTool"; + } + + name = "discord-send-messages"; + + description = `A discord tool useful for sending messages to a discod channel. + Input should be the discord channel message, since we will already have the channel ID.`; + + protected botToken: string; + protected channelId: string; + + client = new Client({ + intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], + }); + + constructor( + channelId: string, + botToken: string | undefined = getEnvironmentVariable("DiscordBotToken") + ) { + 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; + if (!channelId) { + throw new Error( + "Discord channel not set." + ) + } + this.channelId = channelId; + } + + /** @ignore */ + async _call(message: string): Promise { + + await this.client.login(this.botToken); + + const channel = (await this.client.channels.fetch(this.channelId)) as TextChannel; + + if (!channel) { + return "Channel not found"; + } + + if (!(channel instanceof TextChannel)) { + return "Channel is not text channel, cannot send message" + } + + try { + await channel.send(message); + this.client.destroy(); + return "Message sent successfully"; + } + catch (err) { + this.client.destroy(); + console.log("Error sending message:", err); + return "Error sending message"; + } + } +} \ No newline at end of file diff --git a/langchain/src/tools/tests/discord.test.ts b/langchain/src/tools/tests/discord.test.ts index 981c94c86c41..3b3d4d19115c 100644 --- a/langchain/src/tools/tests/discord.test.ts +++ b/langchain/src/tools/tests/discord.test.ts @@ -1,5 +1,5 @@ import { test } from "@jest/globals"; -import { DiscordGetMessagesTool } from "../discord.js"; +import { DiscordGetMessagesTool, DiscordSendMessagesTool } from "../discord.js"; test("DiscordGetMessagesTool", async () => { const tool = new DiscordGetMessagesTool(); @@ -9,4 +9,14 @@ test("DiscordGetMessagesTool", async () => { } catch (error) { console.error(error); } +}); + +test("DiscordSendMessagesTool", async () => { + const tool = new DiscordSendMessagesTool("1153400523718938780"); + try{ + const result = await tool.call("test message from new code"); + console.log(result) + } catch(err){ + console.log(err) + } }); \ No newline at end of file From 5d9bfea47f5b5e1ffd4d96e75be3ce8de9f4d5dc Mon Sep 17 00:00:00 2001 From: slairu Date: Sat, 25 Nov 2023 17:57:11 -0500 Subject: [PATCH 04/18] Added the discord channel search tool. --- langchain/src/tools/discord.ts | 73 +++++++++++++++++++++++ langchain/src/tools/tests/discord.test.ts | 12 +++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/langchain/src/tools/discord.ts b/langchain/src/tools/discord.ts index 31336b6bc3b1..2efc5ffabfc6 100644 --- a/langchain/src/tools/discord.ts +++ b/langchain/src/tools/discord.ts @@ -68,3 +68,76 @@ export class DiscordGetMessagesTool extends Tool { return JSON.stringify(results); } } + +/* + * A tool for searching for messages within 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 the discord channel ID of the channel. + * The _call method takes the search term 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 DiscordChannelSearchTool extends Tool { + static lc_name() { + return "DiscordChannelSearchTool"; + } + + name = "discord_channel_search_tool"; + + description = `a discord toolkit. useful for searching for messages + within a discord channel. input should be the search term. the bot + should have read permissions for the channel`; + + protected botToken: string; + protected channelId: string; + + client = new Client({ + intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], + }); + + constructor( + channelId: string, + botToken: string | undefined = getEnvironmentVariable("DiscordBotToken") + ) { + 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; + if (!channelId) { + throw new Error( + "Discord channel not set." + ) + } + this.channelId = channelId; + } + + /** @ignore */ + async _call(searchTerm: string): Promise { + await this.client.login(this.botToken); + + const channel = (await this.client.channels.fetch(this.channelId)) as TextChannel; + + if (!channel) { + return "Channel not found"; + } + + const messages = await channel.messages.fetch(); + this.client.destroy(); + const filtered = messages.filter((message) => message.content.toLowerCase().includes(searchTerm.toLowerCase())); + + const results = + filtered.map((message) => ({ + author: message.author.tag, + content: message.content, + timestamp: message.createdAt, + })) ?? []; + + return JSON.stringify(results); + } +} \ No newline at end of file diff --git a/langchain/src/tools/tests/discord.test.ts b/langchain/src/tools/tests/discord.test.ts index 981c94c86c41..902d7a8d4038 100644 --- a/langchain/src/tools/tests/discord.test.ts +++ b/langchain/src/tools/tests/discord.test.ts @@ -1,5 +1,5 @@ import { test } from "@jest/globals"; -import { DiscordGetMessagesTool } from "../discord.js"; +import { DiscordGetMessagesTool, DiscordChannelSearchTool } from "../discord.js"; test("DiscordGetMessagesTool", async () => { const tool = new DiscordGetMessagesTool(); @@ -9,4 +9,14 @@ test("DiscordGetMessagesTool", async () => { } catch (error) { console.error(error); } +}); + +test("DiscordChannelSearchTool", async () => { + const tool = new DiscordChannelSearchTool('1153400523718938780'); + try { + const result = await tool.call('Test') + console.log(result) + } catch (error) { + console.error(error); + } }); \ No newline at end of file From 4183f2929263cab66e2e2e119a267179de562051 Mon Sep 17 00:00:00 2001 From: maanethdesilva Date: Mon, 27 Nov 2023 19:31:46 -0500 Subject: [PATCH 05/18] Fixed syntax issue --- langchain/src/tools/tests/discord.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/langchain/src/tools/tests/discord.test.ts b/langchain/src/tools/tests/discord.test.ts index 3f2a61ee0a42..a0ded3c01b39 100644 --- a/langchain/src/tools/tests/discord.test.ts +++ b/langchain/src/tools/tests/discord.test.ts @@ -18,6 +18,8 @@ test("DiscordChannelSearchTool", async () => { console.log(result) } catch (error) { console.error(error); + } +}); test("DiscordSendMessagesTool", async () => { const tool = new DiscordSendMessagesTool("1153400523718938780"); From af2d571c1cf62630e4877dd568f017b1a5480e7b Mon Sep 17 00:00:00 2001 From: sh-hz Date: Mon, 27 Nov 2023 20:33:16 -0500 Subject: [PATCH 06/18] Added get servers & get text channels --- langchain/src/tools/discord.ts | 110 +++++++++++++++++++++- langchain/src/tools/tests/discord.test.ts | 24 ++++- 2 files changed, 131 insertions(+), 3 deletions(-) diff --git a/langchain/src/tools/discord.ts b/langchain/src/tools/discord.ts index 31336b6bc3b1..79c876e8e842 100644 --- a/langchain/src/tools/discord.ts +++ b/langchain/src/tools/discord.ts @@ -1,6 +1,6 @@ import { getEnvironmentVariable } from "../util/env.js"; import { Tool } from "./base.js"; -import { Client, TextChannel, GatewayIntentBits, Message } from "discord.js"; +import { Client, TextChannel, GatewayIntentBits, Message, ChannelType } from "discord.js"; /* * A tool for retrieving messages from a discord channel using a bot. @@ -68,3 +68,111 @@ export class DiscordGetMessagesTool extends Tool { return JSON.stringify(results); } } + +/** + * A tool for retrieving all servers a bot is a member of. It extends the + * base `Tool` class and implements the `_call` method to perform the retrieve + * operation. Requires a bot token which can be set in the environment + * variables. + */ +export class DiscordGetGuildsTool extends Tool { + static lc_name() { + return "DiscordGetGuildsTool"; + } + + name = "discord-get-guilds"; + + description = `a discord tool. useful for getting a list of all servers/guilds the bot is a member of. no input required.`; + + protected botToken: string; + + client = new Client({ + intents: [GatewayIntentBits.Guilds], + }); + + constructor( + botToken: string | undefined = getEnvironmentVariable("DiscordBotToken") + ) { + 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; + } + + /** @ignore */ + async _call(): Promise { + await this.client.login(this.botToken); + + const guilds = await this.client.guilds.fetch(); + this.client.destroy(); + + const results = + guilds.map((guild) => ({ + id: guild.id, + name: guild.name, + createdAt: guild.createdAt, + })) ?? []; + + return JSON.stringify(results); + } +} + +/** + * A tool for retrieving text channels within a server/guild a bot is a member + * of. It extends the base `Tool` class and implements the `_call` method to + * perform the retrieve operation. Requires a bot token which can be set in + * the environment variables. The `_call` method takes a server/guild ID + * to get its text channels. + */ +export class DiscordGetTextChannelsTool extends Tool { + static lc_name() { + return "DiscordGetTextChannelsTool"; + } + + name = "discord-get-text-channels"; + + description = `a discord tool. useful for getting a list of all text channels in a server/guild. input should be a discord server/guild ID`; + + protected botToken: string; + + client = new Client({ + intents: [GatewayIntentBits.Guilds], + }); + + constructor( + botToken: string | undefined = getEnvironmentVariable("DiscordBotToken") + ) { + 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; + } + + /** @ignore */ + async _call(input: string): Promise { + await this.client.login(this.botToken); + + const guild = await this.client.guilds.fetch(input); + const channels = await guild.channels.fetch(); + this.client.destroy(); + + const results = + channels + .filter(channel => channel?.type == ChannelType.GuildText) + .map((channel) => ({ + id: channel?.id, + name: channel?.name, + createdAt: channel?.createdAt, + })) ?? []; + + return JSON.stringify(results); + } +} diff --git a/langchain/src/tools/tests/discord.test.ts b/langchain/src/tools/tests/discord.test.ts index 981c94c86c41..591e54583e67 100644 --- a/langchain/src/tools/tests/discord.test.ts +++ b/langchain/src/tools/tests/discord.test.ts @@ -1,5 +1,5 @@ import { test } from "@jest/globals"; -import { DiscordGetMessagesTool } from "../discord.js"; +import { DiscordGetMessagesTool, DiscordGetGuildsTool, DiscordGetTextChannelsTool } from "../discord.js"; test("DiscordGetMessagesTool", async () => { const tool = new DiscordGetMessagesTool(); @@ -9,4 +9,24 @@ test("DiscordGetMessagesTool", async () => { } catch (error) { console.error(error); } -}); \ No newline at end of file +}); + +test("DiscordGetGuildsTool", async () => { + const tool = new DiscordGetGuildsTool(); + try { + const result = await tool.call(undefined); + console.log(result); + } catch (error) { + console.error(error); + } +}); + +test("DiscordGetTextChannelsTool", async () => { + const tool = new DiscordGetTextChannelsTool(); + try { + const result = await tool.call('1153400523718938775'); + console.log(result); + } catch (error) { + console.error(error); + } +}); From b07c79695afc2cad79b2ebac1848589c03476860 Mon Sep 17 00:00:00 2001 From: maanethdesilva Date: Tue, 28 Nov 2023 18:00:21 -0500 Subject: [PATCH 07/18] Added documentation and examples --- .../docs/integrations/tools/discord.mdx | 31 ++++ examples/src/agents/discord.ts | 27 ++++ examples/src/tools/discord.ts | 34 ++++ langchain/.env.example | 1 + langchain/src/agents/tests/discord.test.ts | 27 ++++ langchain/src/tools/discord.ts | 146 ++++++++++-------- langchain/src/tools/tests/discord.test.ts | 38 +++-- 7 files changed, 221 insertions(+), 83 deletions(-) create mode 100644 docs/core_docs/docs/integrations/tools/discord.mdx create mode 100644 examples/src/agents/discord.ts create mode 100644 examples/src/tools/discord.ts create mode 100644 langchain/src/agents/tests/discord.test.ts diff --git a/docs/core_docs/docs/integrations/tools/discord.mdx b/docs/core_docs/docs/integrations/tools/discord.mdx new file mode 100644 index 000000000000..a55aaf0fce38 --- /dev/null +++ b/docs/core_docs/docs/integrations/tools/discord.mdx @@ -0,0 +1,31 @@ +--- +hide_table_of_contents: true +--- + +import CodeBlock from "@theme/CodeBlock"; + +# Discord Tool + +The Discord Tool gives your agent the ability to search, read, and write messages to discord channels. +It is useful for when you need to interact with a discord channel. + + +## Setup + +To use the Discord Tool you need to install the following official peer depencency: + +```bash npm2yarn +npm install discord.js +``` + +## Usage, standalone + +import ToolExample from "@examples/tools/discord.ts"; + +{ToolExample} + +## Usage, in an Agent + +import AgentExample from "@examples/agents/discord.ts"; + +{AgentExample} diff --git a/examples/src/agents/discord.ts b/examples/src/agents/discord.ts new file mode 100644 index 000000000000..e2a95360fc2c --- /dev/null +++ b/examples/src/agents/discord.ts @@ -0,0 +1,27 @@ +import { OpenAI } from "langchain/llms/openai"; +import { initializeAgentExecutorWithOptions } from "langchain/agents"; +import { DiscordSendMessagesTool } from "langchain/tools/discord"; +import { DadJokeAPI } from "langchain/tools"; + +export default async function run() { + const model = new OpenAI({ + temperature: 0, + }); + + const tools = [ + new DiscordSendMessagesTool("1153400523718938780"), + new DadJokeAPI(), + ]; + + const executor = await initializeAgentExecutorWithOptions(tools, model, { + agentType: "zero-shot-react-description", + verbose: true, + }); + + const res = await executor.call({ + input: `Tell a joke in the discord channel`, + }); + + console.log(res.output); + // "What's the best thing about elevator jokes? They work on so many levels." +} diff --git a/examples/src/tools/discord.ts b/examples/src/tools/discord.ts new file mode 100644 index 000000000000..d91b13b7fab7 --- /dev/null +++ b/examples/src/tools/discord.ts @@ -0,0 +1,34 @@ +import { + DiscordGetMessagesTool, + DiscordChannelSearchTool, + DiscordSendMessagesTool, + DiscordGetGuildsTool, + DiscordGetTextChannelsTool, +} from "langchain/tools/discord"; + +export async function run() { + //Get messages from a channel given channel ID + const getMessageTool = new DiscordGetMessagesTool(); + const messageResults = await getMessageTool.call("1153400523718938780"); + console.log(messageResults); + + //Get guilds/servers + const getGuildsTool = new DiscordGetGuildsTool(); + const guildResults = await getGuildsTool.call(); + console.log(guildResults); + + //Search results in a given channel (case-insensitive) + const searchTool = new DiscordChannelSearchTool("1153400523718938780"); + const searchResults = await searchTool.call("Test"); + console.log(searchResults); + + //Get all text channels of a server + const getChannelsTool = new DiscordGetTextChannelsTool(); + const channelResults = await getChannelsTool.call("1153400523718938775"); + console.log(channelResults); + + //Send a message + const sendMessageTool = new DiscordSendMessagesTool("1153400523718938780"); + const sendMessageResults = await sendMessageTool.call("test message"); + console.log(sendMessageResults); +} diff --git a/langchain/.env.example b/langchain/.env.example index 5c9c2524bcd1..fd1d7e59920c 100644 --- a/langchain/.env.example +++ b/langchain/.env.example @@ -12,6 +12,7 @@ AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME=ADD_YOURS_HERE AZURE_OPENAI_API_VERSION=ADD_YOURS_HERE AZURE_OPENAI_BASE_PATH=ADD_YOURS_HERE CONVEX_URL=ADD_YOURS_HERE +DISCORD_BOT_TOKEN=ADD_YOURS_HERE ELASTIC_URL=http://127.0.0.1:9200 OPENSEARCH_URL=http://127.0.0.1:9200 PINECONE_API_KEY=ADD_YOURS_HERE diff --git a/langchain/src/agents/tests/discord.test.ts b/langchain/src/agents/tests/discord.test.ts new file mode 100644 index 000000000000..23a6f36f0723 --- /dev/null +++ b/langchain/src/agents/tests/discord.test.ts @@ -0,0 +1,27 @@ +import { test } from "@jest/globals"; +import { OpenAI } from "../../llms/openai.js"; +import { initializeAgentExecutorWithOptions } from "../../agents/index.js"; +import { DiscordSendMessagesTool } from "../../tools/discord.js"; +import { DadJokeAPI } from "../../tools/dadjokeapi.js"; + +test.skip("DiscordSendMessagesTool should tell a joke in the discord channel", async () => { + const model = new OpenAI({ + temperature: 0, + }); + + const tools = [ + new DiscordSendMessagesTool("1153400523718938780"), + new DadJokeAPI(), + ]; + + const executor = await initializeAgentExecutorWithOptions(tools, model, { + agentType: "zero-shot-react-description", + verbose: true, + }); + + const res = await executor.call({ + input: `Tell a joke in the discord channel`, + }); + + console.log(res.output); +}); diff --git a/langchain/src/tools/discord.ts b/langchain/src/tools/discord.ts index 2ae6c708e4e7..6518918cd3b8 100644 --- a/langchain/src/tools/discord.ts +++ b/langchain/src/tools/discord.ts @@ -1,8 +1,14 @@ +import { + Client, + TextChannel, + GatewayIntentBits, + Message, + ChannelType, +} from "discord.js"; import { getEnvironmentVariable } from "../util/env.js"; import { Tool } from "./base.js"; -import { Client, TextChannel, GatewayIntentBits, Message, ChannelType } 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 @@ -11,7 +17,6 @@ import { Client, TextChannel, GatewayIntentBits, Message, ChannelType } from "di * 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"; @@ -24,6 +29,7 @@ export class DiscordGetMessagesTool extends Tool { permissions for the channel`; protected botToken: string; + protected messageLimit: number; client = new Client({ @@ -31,14 +37,14 @@ export class DiscordGetMessagesTool extends Tool { }); constructor( - botToken: string | undefined = getEnvironmentVariable("DiscordBotToken"), + botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN"), 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." + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN in your .env file." ); } @@ -57,7 +63,7 @@ export class DiscordGetMessagesTool extends Tool { } const messages = await channel.messages.fetch({ limit: this.messageLimit }); - this.client.destroy(); + await this.client.destroy(); const results = messages.map((message: Message) => ({ author: message.author.tag, @@ -70,9 +76,9 @@ export class DiscordGetMessagesTool extends Tool { } /** - * A tool for retrieving all servers a bot is a member of. It extends the - * base `Tool` class and implements the `_call` method to perform the retrieve - * operation. Requires a bot token which can be set in the environment + * A tool for retrieving all servers a bot is a member of. It extends the + * base `Tool` class and implements the `_call` method to perform the retrieve + * operation. Requires a bot token which can be set in the environment * variables. */ export class DiscordGetGuildsTool extends Tool { @@ -91,13 +97,13 @@ export class DiscordGetGuildsTool extends Tool { }); constructor( - botToken: string | undefined = getEnvironmentVariable("DiscordBotToken") + botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN") ) { super(...arguments); if (!botToken) { throw new Error( - "Discord API key not set. You can set it as DiscordBotToken in your .env file." + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN in your .env file." ); } this.botToken = botToken; @@ -108,7 +114,7 @@ export class DiscordGetGuildsTool extends Tool { await this.client.login(this.botToken); const guilds = await this.client.guilds.fetch(); - this.client.destroy(); + await this.client.destroy(); const results = guilds.map((guild) => ({ @@ -116,16 +122,16 @@ export class DiscordGetGuildsTool extends Tool { name: guild.name, createdAt: guild.createdAt, })) ?? []; - + return JSON.stringify(results); } } /** * A tool for retrieving text channels within a server/guild a bot is a member - * of. It extends the base `Tool` class and implements the `_call` method to - * perform the retrieve operation. Requires a bot token which can be set in - * the environment variables. The `_call` method takes a server/guild ID + * of. It extends the base `Tool` class and implements the `_call` method to + * perform the retrieve operation. Requires a bot token which can be set in + * the environment variables. The `_call` method takes a server/guild ID * to get its text channels. */ export class DiscordGetTextChannelsTool extends Tool { @@ -144,13 +150,13 @@ export class DiscordGetTextChannelsTool extends Tool { }); constructor( - botToken: string | undefined = getEnvironmentVariable("DiscordBotToken") + botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN") ) { super(...arguments); if (!botToken) { throw new Error( - "Discord API key not set. You can set it as DiscordBotToken in your .env file." + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN in your .env file." ); } this.botToken = botToken; @@ -162,29 +168,28 @@ export class DiscordGetTextChannelsTool extends Tool { const guild = await this.client.guilds.fetch(input); const channels = await guild.channels.fetch(); - this.client.destroy(); + await this.client.destroy(); const results = channels - .filter(channel => channel?.type == ChannelType.GuildText) + .filter((channel) => channel?.type === ChannelType.GuildText) .map((channel) => ({ id: channel?.id, name: channel?.name, createdAt: channel?.createdAt, - })) ?? []; + })) ?? []; return JSON.stringify(results); } } -/* +/** * A tool for sending messages to a discord channel using a bot. * It extends the base Tool class and implements the _call method to * perform the retrieve operation. Requires a bot token which can be set - * in the environment variables. The _call method takes the message to be + * in the environment variables. The _call method takes the message to be * sent as the input argument. */ - export class DiscordSendMessagesTool extends Tool { static lc_name() { return "DiscordSendMessagesTool"; @@ -196,6 +201,7 @@ export class DiscordSendMessagesTool extends Tool { Input should be the discord channel message, since we will already have the channel ID.`; protected botToken: string; + protected channelId: string; client = new Client({ @@ -204,53 +210,52 @@ export class DiscordSendMessagesTool extends Tool { constructor( channelId: string, - botToken: string | undefined = getEnvironmentVariable("DiscordBotToken") + botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN") ) { super(...arguments); if (!botToken) { throw new Error( - "Discord API key not set. You can set it as DiscordBotToken in your .env file." + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN in your .env file." ); } this.botToken = botToken; if (!channelId) { - throw new Error( - "Discord channel not set." - ) + throw new Error("Discord channel not set."); } this.channelId = channelId; } - + /** @ignore */ async _call(message: string): Promise { + try { + await this.client.login(this.botToken); - await this.client.login(this.botToken); - - const channel = (await this.client.channels.fetch(this.channelId)) as TextChannel; + const channel = (await this.client.channels.fetch( + this.channelId + )) as TextChannel; - if (!channel) { - return "Channel not found"; - } + if (!channel) { + throw new Error("Channel not found"); + } - if (!(channel instanceof TextChannel)) { - return "Channel is not text channel, cannot send message" - } + if (!(channel.constructor === TextChannel)) { + throw new Error("Channel is not text channel, cannot send message"); + } - try { await channel.send(message); - this.client.destroy(); + + await this.client.destroy(); + return "Message sent successfully"; - } - catch (err) { - this.client.destroy(); - console.log("Error sending message:", err); + } catch (err) { + await this.client.destroy(); return "Error sending message"; } } } -/* +/** * A tool for searching for messages within 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 @@ -259,7 +264,6 @@ export class DiscordSendMessagesTool extends Tool { * 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 DiscordChannelSearchTool extends Tool { static lc_name() { return "DiscordChannelSearchTool"; @@ -272,6 +276,7 @@ export class DiscordChannelSearchTool extends Tool { should have read permissions for the channel`; protected botToken: string; + protected channelId: string; client = new Client({ @@ -280,45 +285,52 @@ export class DiscordChannelSearchTool extends Tool { constructor( channelId: string, - botToken: string | undefined = getEnvironmentVariable("DiscordBotToken") + botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN") ) { super(...arguments); if (!botToken) { throw new Error( - "Discord API key not set. You can set it as DiscordBotToken in your .env file." + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN in your .env file." ); } this.botToken = botToken; if (!channelId) { - throw new Error( - "Discord channel not set." - ) + throw new Error("Discord channel not set."); } this.channelId = channelId; } /** @ignore */ async _call(searchTerm: string): Promise { - await this.client.login(this.botToken); + try { + await this.client.login(this.botToken); - const channel = (await this.client.channels.fetch(this.channelId)) as TextChannel; + const channel = (await this.client.channels.fetch( + this.channelId + )) as TextChannel; - if (!channel) { - return "Channel not found"; - } + if (!channel) { + return "Channel not found"; + } - const messages = await channel.messages.fetch(); - this.client.destroy(); - const filtered = messages.filter((message) => message.content.toLowerCase().includes(searchTerm.toLowerCase())); + const messages = await channel.messages.fetch(); + await this.client.destroy(); + const filtered = messages.filter((message) => + message.content.toLowerCase().includes(searchTerm.toLowerCase()) + ); - const results = - filtered.map((message) => ({ - author: message.author.tag, - content: message.content, - timestamp: message.createdAt, - })) ?? []; + const results = + filtered.map((message) => ({ + author: message.author.tag, + content: message.content, + timestamp: message.createdAt, + })) ?? []; - return JSON.stringify(results); + return JSON.stringify(results); + } catch (err) { + await this.client.destroy(); + return "Error sending message"; + } } } diff --git a/langchain/src/tools/tests/discord.test.ts b/langchain/src/tools/tests/discord.test.ts index 9ec160cae516..d8c549ccb064 100644 --- a/langchain/src/tools/tests/discord.test.ts +++ b/langchain/src/tools/tests/discord.test.ts @@ -1,17 +1,23 @@ import { test } from "@jest/globals"; -import { DiscordGetMessagesTool, DiscordChannelSearchTool, DiscordSendMessagesTool, DiscordGetGuildsTool, DiscordGetTextChannelsTool } from "../discord.js"; +import { + DiscordGetMessagesTool, + DiscordChannelSearchTool, + DiscordSendMessagesTool, + DiscordGetGuildsTool, + DiscordGetTextChannelsTool, +} from "../discord.js"; -test("DiscordGetMessagesTool", async () => { +test.skip("DiscordGetMessagesTool", async () => { const tool = new DiscordGetMessagesTool(); try { - const result = await tool.call('1153400523718938780') - console.log(result) + const result = await tool.call("1153400523718938780"); + console.log(result); } catch (error) { console.error(error); } }); -test("DiscordGetGuildsTool", async () => { +test.skip("DiscordGetGuildsTool", async () => { const tool = new DiscordGetGuildsTool(); try { const result = await tool.call(undefined); @@ -21,32 +27,32 @@ test("DiscordGetGuildsTool", async () => { } }); -test("DiscordChannelSearchTool", async () => { - const tool = new DiscordChannelSearchTool('1153400523718938780'); +test.skip("DiscordChannelSearchTool", async () => { + const tool = new DiscordChannelSearchTool("1153400523718938780"); try { - const result = await tool.call('Test') - console.log(result) + const result = await tool.call("Test"); + console.log(result); } catch (error) { console.error(error); } }); -test("DiscordGetTextChannelsTool", async () => { +test.skip("DiscordGetTextChannelsTool", async () => { const tool = new DiscordGetTextChannelsTool(); try { - const result = await tool.call('1153400523718938775'); + const result = await tool.call("1153400523718938775"); console.log(result); } catch (error) { console.error(error); } }); -test("DiscordSendMessagesTool", async () => { +test.skip("DiscordSendMessagesTool", async () => { const tool = new DiscordSendMessagesTool("1153400523718938780"); - try{ + try { const result = await tool.call("test message from new code"); - console.log(result) - } catch(err){ - console.log(err) + console.log(result); + } catch (err) { + console.log(err); } }); From a52c9858c6affa9b6d721592d2e67c5e92c9e430 Mon Sep 17 00:00:00 2001 From: Jacob Lee Date: Thu, 30 Nov 2023 13:38:17 -0800 Subject: [PATCH 08/18] Rename discord.test.ts to discord.int.test.ts --- .../src/tools/tests/{discord.test.ts => discord.int.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename langchain/src/tools/tests/{discord.test.ts => discord.int.test.ts} (100%) diff --git a/langchain/src/tools/tests/discord.test.ts b/langchain/src/tools/tests/discord.int.test.ts similarity index 100% rename from langchain/src/tools/tests/discord.test.ts rename to langchain/src/tools/tests/discord.int.test.ts From a4f2fcd2f151fe9d1a6f78f3a9c610b5310025d3 Mon Sep 17 00:00:00 2001 From: Jacob Lee Date: Thu, 30 Nov 2023 13:39:55 -0800 Subject: [PATCH 09/18] Rename discord.test.ts to discord.int.test.ts --- .../src/agents/tests/{discord.test.ts => discord.int.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename langchain/src/agents/tests/{discord.test.ts => discord.int.test.ts} (100%) diff --git a/langchain/src/agents/tests/discord.test.ts b/langchain/src/agents/tests/discord.int.test.ts similarity index 100% rename from langchain/src/agents/tests/discord.test.ts rename to langchain/src/agents/tests/discord.int.test.ts From bab4caecae4e321a82b8698431dd77f6822d5a02 Mon Sep 17 00:00:00 2001 From: maanethdesilva Date: Thu, 30 Nov 2023 17:00:28 -0500 Subject: [PATCH 10/18] Passed yarn lint and yarn format --- docs/core_docs/docs/integrations/tools/discord.mdx | 3 +-- examples/src/tools/discord.ts | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/core_docs/docs/integrations/tools/discord.mdx b/docs/core_docs/docs/integrations/tools/discord.mdx index a55aaf0fce38..476d44c99172 100644 --- a/docs/core_docs/docs/integrations/tools/discord.mdx +++ b/docs/core_docs/docs/integrations/tools/discord.mdx @@ -6,10 +6,9 @@ import CodeBlock from "@theme/CodeBlock"; # Discord Tool -The Discord Tool gives your agent the ability to search, read, and write messages to discord channels. +The Discord Tool gives your agent the ability to search, read, and write messages to discord channels. It is useful for when you need to interact with a discord channel. - ## Setup To use the Discord Tool you need to install the following official peer depencency: diff --git a/examples/src/tools/discord.ts b/examples/src/tools/discord.ts index d91b13b7fab7..3a280591024e 100644 --- a/examples/src/tools/discord.ts +++ b/examples/src/tools/discord.ts @@ -7,27 +7,27 @@ import { } from "langchain/tools/discord"; export async function run() { - //Get messages from a channel given channel ID + // Get messages from a channel given channel ID const getMessageTool = new DiscordGetMessagesTool(); const messageResults = await getMessageTool.call("1153400523718938780"); console.log(messageResults); - //Get guilds/servers + // Get guilds/servers const getGuildsTool = new DiscordGetGuildsTool(); const guildResults = await getGuildsTool.call(); console.log(guildResults); - //Search results in a given channel (case-insensitive) + // Search results in a given channel (case-insensitive) const searchTool = new DiscordChannelSearchTool("1153400523718938780"); const searchResults = await searchTool.call("Test"); console.log(searchResults); - //Get all text channels of a server + // Get all text channels of a server const getChannelsTool = new DiscordGetTextChannelsTool(); const channelResults = await getChannelsTool.call("1153400523718938775"); console.log(channelResults); - //Send a message + // Send a message const sendMessageTool = new DiscordSendMessagesTool("1153400523718938780"); const sendMessageResults = await sendMessageTool.call("test message"); console.log(sendMessageResults); From ae30465a0f4d3551cc70d6cbefc0e97a38f7c564 Mon Sep 17 00:00:00 2001 From: maanethdesilva Date: Thu, 30 Nov 2023 19:15:20 -0500 Subject: [PATCH 11/18] Made botToken first argument in tools --- examples/src/agents/discord.ts | 5 +---- examples/src/tools/discord.ts | 6 +++--- langchain/.env.example | 3 ++- .../src/agents/tests/discord.int.test.ts | 5 +---- langchain/src/tools/discord.ts | 20 +++++++++++-------- langchain/src/tools/tests/discord.int.test.ts | 6 +++--- 6 files changed, 22 insertions(+), 23 deletions(-) diff --git a/examples/src/agents/discord.ts b/examples/src/agents/discord.ts index e2a95360fc2c..5125c29a9dd5 100644 --- a/examples/src/agents/discord.ts +++ b/examples/src/agents/discord.ts @@ -8,10 +8,7 @@ export default async function run() { temperature: 0, }); - const tools = [ - new DiscordSendMessagesTool("1153400523718938780"), - new DadJokeAPI(), - ]; + const tools = [new DiscordSendMessagesTool(), new DadJokeAPI()]; const executor = await initializeAgentExecutorWithOptions(tools, model, { agentType: "zero-shot-react-description", diff --git a/examples/src/tools/discord.ts b/examples/src/tools/discord.ts index 3a280591024e..f1808fb06d62 100644 --- a/examples/src/tools/discord.ts +++ b/examples/src/tools/discord.ts @@ -14,11 +14,11 @@ export async function run() { // Get guilds/servers const getGuildsTool = new DiscordGetGuildsTool(); - const guildResults = await getGuildsTool.call(); + const guildResults = await getGuildsTool.call(""); console.log(guildResults); // Search results in a given channel (case-insensitive) - const searchTool = new DiscordChannelSearchTool("1153400523718938780"); + const searchTool = new DiscordChannelSearchTool(); const searchResults = await searchTool.call("Test"); console.log(searchResults); @@ -28,7 +28,7 @@ export async function run() { console.log(channelResults); // Send a message - const sendMessageTool = new DiscordSendMessagesTool("1153400523718938780"); + const sendMessageTool = new DiscordSendMessagesTool(); const sendMessageResults = await sendMessageTool.call("test message"); console.log(sendMessageResults); } diff --git a/langchain/.env.example b/langchain/.env.example index fd72947ef7dc..1f7637d91f7b 100644 --- a/langchain/.env.example +++ b/langchain/.env.example @@ -13,6 +13,7 @@ AZURE_OPENAI_API_VERSION=ADD_YOURS_HERE AZURE_OPENAI_BASE_PATH=ADD_YOURS_HERE CONVEX_URL=ADD_YOURS_HERE DISCORD_BOT_TOKEN=ADD_YOURS_HERE +DISCORD_CHANNEL_ID=ADD_YOURS_HERE ELASTIC_URL=http://127.0.0.1:9200 OPENSEARCH_URL=http://127.0.0.1:9200 PINECONE_API_KEY=ADD_YOURS_HERE @@ -88,4 +89,4 @@ NEO4J_URI=ADD_YOURS_HERE NEO4J_USERNAME=ADD_YOURS_HERE NEO4J_PASSWORD=ADD_YOURS_HERE CLOSEVECTOR_API_KEY=ADD_YOURS_HERE -CLOSEVECTOR_API_SECRET=ADD_YOURS_HERE +CLOSEVECTOR_API_SECRET=ADD_YOURS_HERE \ No newline at end of file diff --git a/langchain/src/agents/tests/discord.int.test.ts b/langchain/src/agents/tests/discord.int.test.ts index 23a6f36f0723..f5710bdd5842 100644 --- a/langchain/src/agents/tests/discord.int.test.ts +++ b/langchain/src/agents/tests/discord.int.test.ts @@ -9,10 +9,7 @@ test.skip("DiscordSendMessagesTool should tell a joke in the discord channel", a temperature: 0, }); - const tools = [ - new DiscordSendMessagesTool("1153400523718938780"), - new DadJokeAPI(), - ]; + const tools = [new DiscordSendMessagesTool(), new DadJokeAPI()]; const executor = await initializeAgentExecutorWithOptions(tools, model, { agentType: "zero-shot-react-description", diff --git a/langchain/src/tools/discord.ts b/langchain/src/tools/discord.ts index 6518918cd3b8..efc3ee5a0ea9 100644 --- a/langchain/src/tools/discord.ts +++ b/langchain/src/tools/discord.ts @@ -38,7 +38,7 @@ export class DiscordGetMessagesTool extends Tool { constructor( botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN"), - messageLimit: number | undefined = 100 + messageLimit: number | undefined = 10 ) { super(...arguments); @@ -110,7 +110,7 @@ export class DiscordGetGuildsTool extends Tool { } /** @ignore */ - async _call(): Promise { + async _call(_input: string): Promise { await this.client.login(this.botToken); const guilds = await this.client.guilds.fetch(); @@ -209,8 +209,8 @@ export class DiscordSendMessagesTool extends Tool { }); constructor( - channelId: string, - botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN") + botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN"), + channelId: string | undefined = getEnvironmentVariable("DISCORD_CHANNEL_ID") ) { super(...arguments); @@ -221,7 +221,9 @@ export class DiscordSendMessagesTool extends Tool { } this.botToken = botToken; if (!channelId) { - throw new Error("Discord channel not set."); + throw new Error( + "Discord channel not set. You can set it as DISCORD_CHANNEL_ID in your .env file." + ); } this.channelId = channelId; } @@ -284,8 +286,8 @@ export class DiscordChannelSearchTool extends Tool { }); constructor( - channelId: string, - botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN") + botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN"), + channelId: string | undefined = getEnvironmentVariable("DISCORD_CHANNEL_ID") ) { super(...arguments); @@ -296,7 +298,9 @@ export class DiscordChannelSearchTool extends Tool { } this.botToken = botToken; if (!channelId) { - throw new Error("Discord channel not set."); + throw new Error( + "Discord channel not set. You can set it as DISCORD_CHANNEL_ID in your .env file." + ); } this.channelId = channelId; } diff --git a/langchain/src/tools/tests/discord.int.test.ts b/langchain/src/tools/tests/discord.int.test.ts index d8c549ccb064..1c86f1e5f461 100644 --- a/langchain/src/tools/tests/discord.int.test.ts +++ b/langchain/src/tools/tests/discord.int.test.ts @@ -20,7 +20,7 @@ test.skip("DiscordGetMessagesTool", async () => { test.skip("DiscordGetGuildsTool", async () => { const tool = new DiscordGetGuildsTool(); try { - const result = await tool.call(undefined); + const result = await tool.call(""); console.log(result); } catch (error) { console.error(error); @@ -28,7 +28,7 @@ test.skip("DiscordGetGuildsTool", async () => { }); test.skip("DiscordChannelSearchTool", async () => { - const tool = new DiscordChannelSearchTool("1153400523718938780"); + const tool = new DiscordChannelSearchTool(); try { const result = await tool.call("Test"); console.log(result); @@ -48,7 +48,7 @@ test.skip("DiscordGetTextChannelsTool", async () => { }); test.skip("DiscordSendMessagesTool", async () => { - const tool = new DiscordSendMessagesTool("1153400523718938780"); + const tool = new DiscordSendMessagesTool(); try { const result = await tool.call("test message from new code"); console.log(result); From 46391e31ec373943eab42f6561b0358e24e27aaa Mon Sep 17 00:00:00 2001 From: your_username Date: Tue, 5 Dec 2023 18:38:01 -0500 Subject: [PATCH 12/18] updated to single object instead of multiple args --- .../src/agents/tests/discord.int.test.ts | 4 +- langchain/src/tools/discord.ts | 145 +++++++++++------- langchain/src/tools/tests/discord.int.test.ts | 32 ++-- 3 files changed, 111 insertions(+), 70 deletions(-) diff --git a/langchain/src/agents/tests/discord.int.test.ts b/langchain/src/agents/tests/discord.int.test.ts index f5710bdd5842..65780a7824d2 100644 --- a/langchain/src/agents/tests/discord.int.test.ts +++ b/langchain/src/agents/tests/discord.int.test.ts @@ -9,14 +9,14 @@ test.skip("DiscordSendMessagesTool should tell a joke in the discord channel", a temperature: 0, }); - const tools = [new DiscordSendMessagesTool(), new DadJokeAPI()]; + const tools = [new DiscordSendMessagesTool({}), new DadJokeAPI()]; const executor = await initializeAgentExecutorWithOptions(tools, model, { agentType: "zero-shot-react-description", verbose: true, }); - const res = await executor.call({ + const res = await executor.invoke({ input: `Tell a joke in the discord channel`, }); diff --git a/langchain/src/tools/discord.ts b/langchain/src/tools/discord.ts index efc3ee5a0ea9..cf8cb31e6fae 100644 --- a/langchain/src/tools/discord.ts +++ b/langchain/src/tools/discord.ts @@ -8,6 +8,21 @@ import { import { getEnvironmentVariable } from "../util/env.js"; import { Tool } from "./base.js"; +interface DiscordGetMessagesToolParams { + botToken?: string; + messageLimit?: number; +} + +interface DiscordSendMessageToolParams { + botToken?: string; + channelId?: string; +} + +interface DiscordToolParams { + botToken?: string; +} + + /** * A tool for retrieving messages from a discord channel using a bot. * It extends the base Tool class and implements the _call method to @@ -36,19 +51,23 @@ export class DiscordGetMessagesTool extends Tool { intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], }); - constructor( - botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN"), - messageLimit: number | undefined = 10 - ) { - super(...arguments); + constructor(params: DiscordGetMessagesToolParams) { + super(); + + const { botToken, messageLimit = 10 } = params; if (!botToken) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN in your .env file." - ); + const envBotToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"); + if (!envBotToken) { + throw new Error( + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + ); + } + this.botToken = envBotToken; + } else { + this.botToken = botToken; } - this.botToken = botToken; this.messageLimit = messageLimit; } @@ -96,17 +115,22 @@ export class DiscordGetGuildsTool extends Tool { intents: [GatewayIntentBits.Guilds], }); - constructor( - botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN") - ) { - super(...arguments); + constructor(params: DiscordToolParams) { + super(); + + const { botToken } = params; if (!botToken) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN in your .env file." - ); + const envBotToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"); + if (!envBotToken) { + throw new Error( + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + ); + } + this.botToken = envBotToken; + } else { + this.botToken = botToken; } - this.botToken = botToken; } /** @ignore */ @@ -149,17 +173,22 @@ export class DiscordGetTextChannelsTool extends Tool { intents: [GatewayIntentBits.Guilds], }); - constructor( - botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN") - ) { - super(...arguments); + constructor(params: DiscordToolParams) { + super(); + + const { botToken } = params; if (!botToken) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN in your .env file." - ); + const envBotToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"); + if (!envBotToken) { + throw new Error( + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + ); + } + this.botToken = envBotToken; + } else { + this.botToken = botToken; } - this.botToken = botToken; } /** @ignore */ @@ -208,24 +237,35 @@ export class DiscordSendMessagesTool extends Tool { intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], }); - constructor( - botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN"), - channelId: string | undefined = getEnvironmentVariable("DISCORD_CHANNEL_ID") - ) { - super(...arguments); + constructor(params: DiscordSendMessageToolParams) { + super(); + + const { botToken, channelId } = params; if (!botToken) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN in your .env file." - ); + const envBotToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"); + if (!envBotToken) { + throw new Error( + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + ); + } + this.botToken = envBotToken; + } else { + this.botToken = botToken; } - this.botToken = botToken; + if (!channelId) { - throw new Error( - "Discord channel not set. You can set it as DISCORD_CHANNEL_ID in your .env file." - ); + const envChannelId = getEnvironmentVariable("DISCORD_CHANNEL_ID"); + if (!envChannelId) { + throw new Error( + "Discord API key not set. You can set it as DISCORD_CHANNEL_ID" + ); + } + this.channelId = envChannelId; + } else { + this.channelId = channelId; } - this.channelId = channelId; + } /** @ignore */ @@ -285,24 +325,23 @@ export class DiscordChannelSearchTool extends Tool { intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], }); - constructor( - botToken: string | undefined = getEnvironmentVariable("DISCORD_BOT_TOKEN"), - channelId: string | undefined = getEnvironmentVariable("DISCORD_CHANNEL_ID") - ) { - super(...arguments); + constructor(params: DiscordToolParams) { + super(); + + const { botToken } = params; if (!botToken) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN in your .env file." - ); - } - this.botToken = botToken; - if (!channelId) { - throw new Error( - "Discord channel not set. You can set it as DISCORD_CHANNEL_ID in your .env file." - ); + const envBotToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"); + if (!envBotToken) { + throw new Error( + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + ); + } + this.botToken = envBotToken; + } else { + this.botToken = botToken; } - this.channelId = channelId; + } /** @ignore */ diff --git a/langchain/src/tools/tests/discord.int.test.ts b/langchain/src/tools/tests/discord.int.test.ts index 1c86f1e5f461..6cd7b142a4cf 100644 --- a/langchain/src/tools/tests/discord.int.test.ts +++ b/langchain/src/tools/tests/discord.int.test.ts @@ -7,50 +7,52 @@ import { DiscordGetTextChannelsTool, } from "../discord.js"; -test.skip("DiscordGetMessagesTool", async () => { - const tool = new DiscordGetMessagesTool(); + +test("DiscordGetMessagesTool", async () => { + const tool = new DiscordGetMessagesTool({}); + try { - const result = await tool.call("1153400523718938780"); + const result = await tool.invoke("1153400523718938780"); console.log(result); } catch (error) { console.error(error); } }); -test.skip("DiscordGetGuildsTool", async () => { - const tool = new DiscordGetGuildsTool(); +test("DiscordGetGuildsTool", async () => { + const tool = new DiscordGetGuildsTool({}); try { - const result = await tool.call(""); + const result = await tool.invoke(""); console.log(result); } catch (error) { console.error(error); } }); -test.skip("DiscordChannelSearchTool", async () => { - const tool = new DiscordChannelSearchTool(); +test("DiscordChannelSearchTool", async () => { + const tool = new DiscordChannelSearchTool({}); try { - const result = await tool.call("Test"); + const result = await tool.invoke("Test"); console.log(result); } catch (error) { console.error(error); } }); -test.skip("DiscordGetTextChannelsTool", async () => { - const tool = new DiscordGetTextChannelsTool(); +test("DiscordGetTextChannelsTool", async () => { + const tool = new DiscordGetTextChannelsTool({}); try { - const result = await tool.call("1153400523718938775"); + const result = await tool.invoke("1153400523718938775"); console.log(result); } catch (error) { console.error(error); } }); -test.skip("DiscordSendMessagesTool", async () => { - const tool = new DiscordSendMessagesTool(); +test("DiscordSendMessagesTool", async () => { + const tool = new DiscordSendMessagesTool({}); try { - const result = await tool.call("test message from new code"); + const result = await tool.invoke("test message from new code"); console.log(result); } catch (err) { console.log(err); From 0d085b6fb350267352a71b8ab3b7e6bc05ee4a61 Mon Sep 17 00:00:00 2001 From: maanethdesilva Date: Tue, 5 Dec 2023 19:24:04 -0500 Subject: [PATCH 13/18] fixed discord arguments to use fields --- .../src/agents/tests/discord.int.test.ts | 4 +- langchain/src/tools/discord.ts | 146 +++++++++--------- langchain/src/tools/tests/discord.int.test.ts | 21 ++- 3 files changed, 84 insertions(+), 87 deletions(-) diff --git a/langchain/src/agents/tests/discord.int.test.ts b/langchain/src/agents/tests/discord.int.test.ts index 65780a7824d2..0d5095582196 100644 --- a/langchain/src/agents/tests/discord.int.test.ts +++ b/langchain/src/agents/tests/discord.int.test.ts @@ -9,7 +9,7 @@ test.skip("DiscordSendMessagesTool should tell a joke in the discord channel", a temperature: 0, }); - const tools = [new DiscordSendMessagesTool({}), new DadJokeAPI()]; + const tools = [new DiscordSendMessagesTool(), new DadJokeAPI()]; const executor = await initializeAgentExecutorWithOptions(tools, model, { agentType: "zero-shot-react-description", @@ -17,7 +17,7 @@ test.skip("DiscordSendMessagesTool should tell a joke in the discord channel", a }); const res = await executor.invoke({ - input: `Tell a joke in the discord channel`, + input: `Tell 2 jokes in the discord channel`, }); console.log(res.output); diff --git a/langchain/src/tools/discord.ts b/langchain/src/tools/discord.ts index cf8cb31e6fae..7144433fbbb6 100644 --- a/langchain/src/tools/discord.ts +++ b/langchain/src/tools/discord.ts @@ -8,21 +8,33 @@ import { import { getEnvironmentVariable } from "../util/env.js"; import { Tool } from "./base.js"; -interface DiscordGetMessagesToolParams { +/** + * Base tool parameters for the Discord tools + */ +interface DiscordToolParams { botToken?: string; +} + +/** + * Tool parameters for the DiscordGetMessagesTool + */ +interface DiscordGetMessagesToolParams extends DiscordToolParams { messageLimit?: number; } -interface DiscordSendMessageToolParams { - botToken?: string; +/** + * Tool parameters for the DiscordSendMessageTool + */ +interface DiscordSendMessageToolParams extends DiscordToolParams { channelId?: string; } -interface DiscordToolParams { - botToken?: string; +/** + * Tool parameters for the DiscordChannelSearch + */ +interface DiscordChannelSearchParams extends DiscordToolParams { + channelId?: string; } - - /** * A tool for retrieving messages from a discord channel using a bot. * It extends the base Tool class and implements the _call method to @@ -51,23 +63,21 @@ export class DiscordGetMessagesTool extends Tool { intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], }); - constructor(params: DiscordGetMessagesToolParams) { + constructor(fields: DiscordGetMessagesToolParams = {}) { super(); - const { botToken, messageLimit = 10 } = params; + const { + botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), + messageLimit = 10, + } = fields; if (!botToken) { - const envBotToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"); - if (!envBotToken) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" - ); - } - this.botToken = envBotToken; - } else { - this.botToken = botToken; + throw new Error( + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + ); } + this.botToken = botToken; this.messageLimit = messageLimit; } @@ -115,22 +125,18 @@ export class DiscordGetGuildsTool extends Tool { intents: [GatewayIntentBits.Guilds], }); - constructor(params: DiscordToolParams) { + constructor(fields: DiscordToolParams = {}) { super(); - const { botToken } = params; + const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN") } = + fields || {}; if (!botToken) { - const envBotToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"); - if (!envBotToken) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" - ); - } - this.botToken = envBotToken; - } else { - this.botToken = botToken; + throw new Error( + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + ); } + this.botToken = botToken; } /** @ignore */ @@ -173,22 +179,18 @@ export class DiscordGetTextChannelsTool extends Tool { intents: [GatewayIntentBits.Guilds], }); - constructor(params: DiscordToolParams) { + constructor(fields: DiscordToolParams = {}) { super(); - const { botToken } = params; + const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN") } = + fields || {}; if (!botToken) { - const envBotToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"); - if (!envBotToken) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" - ); - } - this.botToken = envBotToken; - } else { - this.botToken = botToken; + throw new Error( + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + ); } + this.botToken = botToken; } /** @ignore */ @@ -215,7 +217,7 @@ export class DiscordGetTextChannelsTool extends Tool { /** * A tool for sending messages to a discord channel using a bot. * It extends the base Tool class and implements the _call method to - * perform the retrieve operation. Requires a bot token which can be set + * perform the retrieve operation. Requires a bot token and channelId which can be set * in the environment variables. The _call method takes the message to be * sent as the input argument. */ @@ -237,35 +239,27 @@ export class DiscordSendMessagesTool extends Tool { intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], }); - constructor(params: DiscordSendMessageToolParams) { + constructor(fields: DiscordSendMessageToolParams = {}) { super(); - const { botToken, channelId } = params; + const { + botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), + channelId = getEnvironmentVariable("DISCORD_CHANNEL_ID"), + } = fields; if (!botToken) { - const envBotToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"); - if (!envBotToken) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" - ); - } - this.botToken = envBotToken; - } else { - this.botToken = botToken; + throw new Error( + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + ); } if (!channelId) { - const envChannelId = getEnvironmentVariable("DISCORD_CHANNEL_ID"); - if (!envChannelId) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_CHANNEL_ID" - ); - } - this.channelId = envChannelId; - } else { - this.channelId = channelId; + throw new Error( + "Discord API key not set. You can set it as DISCORD_CHANNEL_ID" + ); } - + this.botToken = botToken; + this.channelId = channelId; } /** @ignore */ @@ -325,23 +319,27 @@ export class DiscordChannelSearchTool extends Tool { intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], }); - constructor(params: DiscordToolParams) { + constructor(fields: DiscordChannelSearchParams = {}) { super(); - const { botToken } = params; + const { + botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), + channelId = getEnvironmentVariable("DISCORD_CHANNEL_ID"), + } = fields; if (!botToken) { - const envBotToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"); - if (!envBotToken) { - throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" - ); - } - this.botToken = envBotToken; - } else { - this.botToken = botToken; + throw new Error( + "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + ); } + if (!channelId) { + throw new Error( + "Discord API key not set. You can set it as DISCORD_CHANNEL_ID" + ); + } + this.botToken = botToken; + this.channelId = channelId; } /** @ignore */ @@ -373,7 +371,7 @@ export class DiscordChannelSearchTool extends Tool { return JSON.stringify(results); } catch (err) { await this.client.destroy(); - return "Error sending message"; + return "Error searching through channel."; } } } diff --git a/langchain/src/tools/tests/discord.int.test.ts b/langchain/src/tools/tests/discord.int.test.ts index 6cd7b142a4cf..00f5bbb431d4 100644 --- a/langchain/src/tools/tests/discord.int.test.ts +++ b/langchain/src/tools/tests/discord.int.test.ts @@ -7,9 +7,8 @@ import { DiscordGetTextChannelsTool, } from "../discord.js"; - -test("DiscordGetMessagesTool", async () => { - const tool = new DiscordGetMessagesTool({}); +test.skip("DiscordGetMessagesTool", async () => { + const tool = new DiscordGetMessagesTool(); try { const result = await tool.invoke("1153400523718938780"); @@ -19,8 +18,8 @@ test("DiscordGetMessagesTool", async () => { } }); -test("DiscordGetGuildsTool", async () => { - const tool = new DiscordGetGuildsTool({}); +test.skip("DiscordGetGuildsTool", async () => { + const tool = new DiscordGetGuildsTool(); try { const result = await tool.invoke(""); console.log(result); @@ -29,8 +28,8 @@ test("DiscordGetGuildsTool", async () => { } }); -test("DiscordChannelSearchTool", async () => { - const tool = new DiscordChannelSearchTool({}); +test.skip("DiscordChannelSearchTool", async () => { + const tool = new DiscordChannelSearchTool(); try { const result = await tool.invoke("Test"); console.log(result); @@ -39,8 +38,8 @@ test("DiscordChannelSearchTool", async () => { } }); -test("DiscordGetTextChannelsTool", async () => { - const tool = new DiscordGetTextChannelsTool({}); +test.skip("DiscordGetTextChannelsTool", async () => { + const tool = new DiscordGetTextChannelsTool(); try { const result = await tool.invoke("1153400523718938775"); console.log(result); @@ -49,8 +48,8 @@ test("DiscordGetTextChannelsTool", async () => { } }); -test("DiscordSendMessagesTool", async () => { - const tool = new DiscordSendMessagesTool({}); +test.skip("DiscordSendMessagesTool", async () => { + const tool = new DiscordSendMessagesTool(); try { const result = await tool.invoke("test message from new code"); console.log(result); From 652417cd30496fdd816f255c804dd81d6c54c439 Mon Sep 17 00:00:00 2001 From: maanethdesilva Date: Tue, 5 Dec 2023 19:25:17 -0500 Subject: [PATCH 14/18] updated agent test --- langchain/src/agents/tests/discord.int.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain/src/agents/tests/discord.int.test.ts b/langchain/src/agents/tests/discord.int.test.ts index 0d5095582196..df716f3f0001 100644 --- a/langchain/src/agents/tests/discord.int.test.ts +++ b/langchain/src/agents/tests/discord.int.test.ts @@ -17,7 +17,7 @@ test.skip("DiscordSendMessagesTool should tell a joke in the discord channel", a }); const res = await executor.invoke({ - input: `Tell 2 jokes in the discord channel`, + input: `Tell a joke in the discord channel`, }); console.log(res.output); From 3076fd4ce77cac7bc4d8c387f3342da53896e4a5 Mon Sep 17 00:00:00 2001 From: maanethdesilva Date: Fri, 8 Dec 2023 14:37:56 -0500 Subject: [PATCH 15/18] Made requested changes --- examples/src/agents/discord.ts | 30 ++- examples/src/tools/discord.ts | 42 ++-- .../src/agents/tests/discord.int.test.ts | 6 +- langchain/src/tools/discord.ts | 208 +++++++++++------- langchain/src/tools/tests/discord.int.test.ts | 20 +- 5 files changed, 177 insertions(+), 129 deletions(-) diff --git a/examples/src/agents/discord.ts b/examples/src/agents/discord.ts index 5125c29a9dd5..4de1f8b2300d 100644 --- a/examples/src/agents/discord.ts +++ b/examples/src/agents/discord.ts @@ -1,24 +1,22 @@ -import { OpenAI } from "langchain/llms/openai"; +import { ChatOpenAI } from "langchain/chat_models/openai"; import { initializeAgentExecutorWithOptions } from "langchain/agents"; import { DiscordSendMessagesTool } from "langchain/tools/discord"; import { DadJokeAPI } from "langchain/tools"; -export default async function run() { - const model = new OpenAI({ - temperature: 0, - }); +const model = new ChatOpenAI({ + temperature: 0, +}); - const tools = [new DiscordSendMessagesTool(), new DadJokeAPI()]; +const tools = [new DiscordSendMessagesTool(), new DadJokeAPI()]; - const executor = await initializeAgentExecutorWithOptions(tools, model, { - agentType: "zero-shot-react-description", - verbose: true, - }); +const executor = await initializeAgentExecutorWithOptions(tools, model, { + agentType: "zero-shot-react-description", + verbose: true, +}); - const res = await executor.call({ - input: `Tell a joke in the discord channel`, - }); +const res = await executor.call({ + input: `Tell a joke in the discord channel`, +}); - console.log(res.output); - // "What's the best thing about elevator jokes? They work on so many levels." -} +console.log(res.output); +// "What's the best thing about elevator jokes? They work on so many levels." diff --git a/examples/src/tools/discord.ts b/examples/src/tools/discord.ts index f1808fb06d62..30155f3da6e9 100644 --- a/examples/src/tools/discord.ts +++ b/examples/src/tools/discord.ts @@ -6,29 +6,27 @@ import { DiscordGetTextChannelsTool, } from "langchain/tools/discord"; -export async function run() { - // Get messages from a channel given channel ID - const getMessageTool = new DiscordGetMessagesTool(); - const messageResults = await getMessageTool.call("1153400523718938780"); - console.log(messageResults); +// Get messages from a channel given channel ID +const getMessageTool = new DiscordGetMessagesTool(); +const messageResults = await getMessageTool.call("1153400523718938780"); +console.log(messageResults); - // Get guilds/servers - const getGuildsTool = new DiscordGetGuildsTool(); - const guildResults = await getGuildsTool.call(""); - console.log(guildResults); +// Get guilds/servers +const getGuildsTool = new DiscordGetGuildsTool(); +const guildResults = await getGuildsTool.call(""); +console.log(guildResults); - // Search results in a given channel (case-insensitive) - const searchTool = new DiscordChannelSearchTool(); - const searchResults = await searchTool.call("Test"); - console.log(searchResults); +// Search results in a given channel (case-insensitive) +const searchTool = new DiscordChannelSearchTool(); +const searchResults = await searchTool.call("Test"); +console.log(searchResults); - // Get all text channels of a server - const getChannelsTool = new DiscordGetTextChannelsTool(); - const channelResults = await getChannelsTool.call("1153400523718938775"); - console.log(channelResults); +// Get all text channels of a server +const getChannelsTool = new DiscordGetTextChannelsTool(); +const channelResults = await getChannelsTool.call("1153400523718938775"); +console.log(channelResults); - // Send a message - const sendMessageTool = new DiscordSendMessagesTool(); - const sendMessageResults = await sendMessageTool.call("test message"); - console.log(sendMessageResults); -} +// Send a message +const sendMessageTool = new DiscordSendMessagesTool(); +const sendMessageResults = await sendMessageTool.call("test message"); +console.log(sendMessageResults); diff --git a/langchain/src/agents/tests/discord.int.test.ts b/langchain/src/agents/tests/discord.int.test.ts index df716f3f0001..8ee54fb262bf 100644 --- a/langchain/src/agents/tests/discord.int.test.ts +++ b/langchain/src/agents/tests/discord.int.test.ts @@ -1,11 +1,11 @@ import { test } from "@jest/globals"; -import { OpenAI } from "../../llms/openai.js"; +import { ChatOpenAI } from "../../chat_models/openai.js"; import { initializeAgentExecutorWithOptions } from "../../agents/index.js"; import { DiscordSendMessagesTool } from "../../tools/discord.js"; import { DadJokeAPI } from "../../tools/dadjokeapi.js"; -test.skip("DiscordSendMessagesTool should tell a joke in the discord channel", async () => { - const model = new OpenAI({ +test("DiscordSendMessagesTool should tell a joke in the discord channel", async () => { + const model = new ChatOpenAI({ temperature: 0, }); diff --git a/langchain/src/tools/discord.ts b/langchain/src/tools/discord.ts index 7144433fbbb6..40f237377727 100644 --- a/langchain/src/tools/discord.ts +++ b/langchain/src/tools/discord.ts @@ -13,6 +13,7 @@ import { Tool } from "./base.js"; */ interface DiscordToolParams { botToken?: string; + client?: Client; } /** @@ -51,56 +52,68 @@ export class DiscordGetMessagesTool extends Tool { 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`; + 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], - }); + protected client: Client; - constructor(fields: DiscordGetMessagesToolParams = {}) { + constructor(fields?: DiscordGetMessagesToolParams) { super(); const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), messageLimit = 10, - } = fields; + client, + } = fields ?? {}; if (!botToken) { throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + "Environment variable DISCORD_BOT_TOKEN missing, but is required for DiscordGetMessagesTool." ); } + this.client = + client ?? + new Client({ + intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], + }); + this.botToken = botToken; this.messageLimit = messageLimit; } /** @ignore */ async _call(input: string): Promise { - await this.client.login(this.botToken); + try { + await this.client.login(this.botToken); - const channel = (await this.client.channels.fetch(input)) as TextChannel; + const channel = (await this.client.channels.fetch(input)) as TextChannel; - if (!channel) { - return "Channel not found"; - } + if (!channel) { + return "Channel not found."; + } - const messages = await channel.messages.fetch({ limit: this.messageLimit }); - await this.client.destroy(); - const results = - messages.map((message: Message) => ({ - author: message.author.tag, - content: message.content, - timestamp: message.createdAt, - })) ?? []; + const messages = await channel.messages.fetch({ + limit: this.messageLimit, + }); + await this.client.destroy(); + const results = + messages.map((message: Message) => ({ + author: message.author.tag, + content: message.content, + timestamp: message.createdAt, + })) ?? []; - return JSON.stringify(results); + return JSON.stringify(results); + } catch (err) { + await this.client.destroy(); + return "Error getting messages."; + } } } @@ -117,43 +130,52 @@ export class DiscordGetGuildsTool extends Tool { name = "discord-get-guilds"; - description = `a discord tool. useful for getting a list of all servers/guilds the bot is a member of. no input required.`; + description = `A discord tool. Useful for getting a list of all servers/guilds the bot is a member of. No input required.`; protected botToken: string; - client = new Client({ - intents: [GatewayIntentBits.Guilds], - }); + protected client: Client; - constructor(fields: DiscordToolParams = {}) { + constructor(fields?: DiscordToolParams) { super(); - const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN") } = - fields || {}; + const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), client } = + fields ?? {}; if (!botToken) { throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + "Environment variable DISCORD_BOT_TOKEN missing, but is required for DiscordGetGuildsTool." ); } + this.client = + client ?? + new Client({ + intents: [GatewayIntentBits.Guilds], + }); + this.botToken = botToken; } /** @ignore */ async _call(_input: string): Promise { - await this.client.login(this.botToken); + try { + await this.client.login(this.botToken); - const guilds = await this.client.guilds.fetch(); - await this.client.destroy(); + const guilds = await this.client.guilds.fetch(); + await this.client.destroy(); - const results = - guilds.map((guild) => ({ - id: guild.id, - name: guild.name, - createdAt: guild.createdAt, - })) ?? []; + const results = + guilds.map((guild) => ({ + id: guild.id, + name: guild.name, + createdAt: guild.createdAt, + })) ?? []; - return JSON.stringify(results); + return JSON.stringify(results); + } catch (err) { + await this.client.destroy(); + return "Error getting guilds."; + } } } @@ -171,46 +193,54 @@ export class DiscordGetTextChannelsTool extends Tool { name = "discord-get-text-channels"; - description = `a discord tool. useful for getting a list of all text channels in a server/guild. input should be a discord server/guild ID`; + description = `A discord tool. Useful for getting a list of all text channels in a server/guild. Input should be a discord server/guild ID.`; protected botToken: string; - client = new Client({ - intents: [GatewayIntentBits.Guilds], - }); + protected client: Client; - constructor(fields: DiscordToolParams = {}) { + constructor(fields?: DiscordToolParams) { super(); - const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN") } = - fields || {}; + const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), client } = + fields ?? {}; if (!botToken) { throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + "Environment variable DISCORD_BOT_TOKEN missing, but is required for DiscordGetTextChannelsTool." ); } + this.client = + client ?? + new Client({ + intents: [GatewayIntentBits.Guilds], + }); this.botToken = botToken; } /** @ignore */ async _call(input: string): Promise { - await this.client.login(this.botToken); - - const guild = await this.client.guilds.fetch(input); - const channels = await guild.channels.fetch(); - await this.client.destroy(); - - const results = - channels - .filter((channel) => channel?.type === ChannelType.GuildText) - .map((channel) => ({ - id: channel?.id, - name: channel?.name, - createdAt: channel?.createdAt, - })) ?? []; + try { + await this.client.login(this.botToken); + + const guild = await this.client.guilds.fetch(input); + const channels = await guild.channels.fetch(); + await this.client.destroy(); - return JSON.stringify(results); + const results = + channels + .filter((channel) => channel?.type === ChannelType.GuildText) + .map((channel) => ({ + id: channel?.id, + name: channel?.name, + createdAt: channel?.createdAt, + })) ?? []; + + return JSON.stringify(results); + } catch (err) { + await this.client.destroy(); + return "Error getting text channels."; + } } } @@ -235,29 +265,35 @@ export class DiscordSendMessagesTool extends Tool { protected channelId: string; - client = new Client({ - intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], - }); + protected client: Client; - constructor(fields: DiscordSendMessageToolParams = {}) { + constructor(fields?: DiscordSendMessageToolParams) { super(); const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), channelId = getEnvironmentVariable("DISCORD_CHANNEL_ID"), - } = fields; + client, + } = fields ?? {}; if (!botToken) { throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + "Environment variable DISCORD_BOT_TOKEN missing, but is required for DiscordSendMessagesTool." ); } if (!channelId) { throw new Error( - "Discord API key not set. You can set it as DISCORD_CHANNEL_ID" + "Environment variable DISCORD_CHANNEL_ID missing, but is required for DiscordSendMessagesTool." ); } + + this.client = + client ?? + new Client({ + intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], + }); + this.botToken = botToken; this.channelId = channelId; } @@ -283,10 +319,10 @@ export class DiscordSendMessagesTool extends Tool { await this.client.destroy(); - return "Message sent successfully"; + return "Message sent successfully."; } catch (err) { await this.client.destroy(); - return "Error sending message"; + return "Error sending message."; } } } @@ -307,37 +343,43 @@ export class DiscordChannelSearchTool extends Tool { name = "discord_channel_search_tool"; - description = `a discord toolkit. useful for searching for messages - within a discord channel. input should be the search term. the bot - should have read permissions for the channel`; + description = `A discord toolkit. Useful for searching for messages + within a discord channel. Input should be the search term. The bot + should have read permissions for the channel.`; protected botToken: string; protected channelId: string; - client = new Client({ - intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], - }); + protected client: Client; - constructor(fields: DiscordChannelSearchParams = {}) { + constructor(fields?: DiscordChannelSearchParams) { super(); const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), channelId = getEnvironmentVariable("DISCORD_CHANNEL_ID"), - } = fields; + client, + } = fields ?? {}; if (!botToken) { throw new Error( - "Discord API key not set. You can set it as DISCORD_BOT_TOKEN" + "Environment variable DISCORD_BOT_TOKEN missing, but is required for DiscordChannelSearchTool." ); } if (!channelId) { throw new Error( - "Discord API key not set. You can set it as DISCORD_CHANNEL_ID" + "Environment variable DISCORD_CHANNEL_ID missing, but is required for DiscordChannelSearchTool." ); } + + this.client = + client ?? + new Client({ + intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], + }); + this.botToken = botToken; this.channelId = channelId; } diff --git a/langchain/src/tools/tests/discord.int.test.ts b/langchain/src/tools/tests/discord.int.test.ts index 00f5bbb431d4..feee6e22bb2e 100644 --- a/langchain/src/tools/tests/discord.int.test.ts +++ b/langchain/src/tools/tests/discord.int.test.ts @@ -7,52 +7,62 @@ import { DiscordGetTextChannelsTool, } from "../discord.js"; -test.skip("DiscordGetMessagesTool", async () => { +test("DiscordGetMessagesTool", async () => { const tool = new DiscordGetMessagesTool(); try { const result = await tool.invoke("1153400523718938780"); console.log(result); + expect(result).toBeTruthy(); + expect(result).not.toEqual("Channel not found."); + expect(result).not.toEqual("Error getting messages."); } catch (error) { console.error(error); } }); -test.skip("DiscordGetGuildsTool", async () => { +test("DiscordGetGuildsTool", async () => { const tool = new DiscordGetGuildsTool(); try { const result = await tool.invoke(""); console.log(result); + expect(result).toBeTruthy(); + expect(result).not.toEqual("Error getting guilds."); } catch (error) { console.error(error); } }); -test.skip("DiscordChannelSearchTool", async () => { +test("DiscordChannelSearchTool", async () => { const tool = new DiscordChannelSearchTool(); try { const result = await tool.invoke("Test"); console.log(result); + expect(result).toBeTruthy(); + expect(result).not.toEqual("Error searching through channel."); } catch (error) { console.error(error); } }); -test.skip("DiscordGetTextChannelsTool", async () => { +test("DiscordGetTextChannelsTool", async () => { const tool = new DiscordGetTextChannelsTool(); try { const result = await tool.invoke("1153400523718938775"); console.log(result); + expect(result).toBeTruthy(); + expect(result).not.toEqual("Error getting text channels."); } catch (error) { console.error(error); } }); -test.skip("DiscordSendMessagesTool", async () => { +test("DiscordSendMessagesTool", async () => { const tool = new DiscordSendMessagesTool(); try { const result = await tool.invoke("test message from new code"); console.log(result); + expect(result).toEqual("Message sent successfully."); } catch (err) { console.log(err); } From 40c23a14d50fcc1a51ebe23dd8de8099e3fd7353 Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Tue, 12 Dec 2023 12:27:48 -0800 Subject: [PATCH 16/18] Move to community --- docs/api_refs/typedoc.json | 1 - examples/package.json | 1 + examples/src/agents/discord.ts | 2 +- examples/src/tools/discord.ts | 12 +++++----- langchain/.gitignore | 3 --- langchain/package.json | 10 -------- langchain/scripts/create-entrypoints.js | 2 -- .../src/agents/tests/discord.int.test.ts | 24 ------------------- langchain/src/load/import_constants.ts | 1 - langchain/src/load/import_type.d.ts | 3 --- langchain/tools/discord.cjs | 1 + langchain/tools/discord.d.ts | 1 + langchain/tools/discord.js | 1 + libs/langchain-community/.gitignore | 3 +++ libs/langchain-community/package.json | 13 ++++++++++ .../scripts/check-tree-shaking.js | 1 + .../scripts/create-entrypoints.js | 2 ++ .../src/load/import_constants.ts | 1 + .../src/load/import_type.d.ts | 3 +++ .../langchain-community}/src/tools/discord.ts | 4 ++-- .../src/tools/tests/discord.int.test.ts | 10 ++++---- yarn.lock | 9 ++++--- 22 files changed, 47 insertions(+), 61 deletions(-) delete mode 100644 langchain/src/agents/tests/discord.int.test.ts create mode 100644 langchain/tools/discord.cjs create mode 100644 langchain/tools/discord.d.ts create mode 100644 langchain/tools/discord.js rename {langchain => libs/langchain-community}/src/tools/discord.ts (98%) rename {langchain => libs/langchain-community}/src/tools/tests/discord.int.test.ts (86%) diff --git a/docs/api_refs/typedoc.json b/docs/api_refs/typedoc.json index c785bbef5e09..378c86f4d173 100644 --- a/docs/api_refs/typedoc.json +++ b/docs/api_refs/typedoc.json @@ -39,7 +39,6 @@ "./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/connery.ts", "./langchain/src/tools/render.ts", "./langchain/src/tools/sql.ts", diff --git a/examples/package.json b/examples/package.json index bbc292a7a930..477068885925 100644 --- a/examples/package.json +++ b/examples/package.json @@ -27,6 +27,7 @@ "@getmetal/metal-sdk": "^4.0.0", "@getzep/zep-js": "^0.9.0", "@gomomento/sdk": "^1.51.1", + "@langchain/community": "workspace:*", "@opensearch-project/opensearch": "^2.2.0", "@pinecone-database/pinecone": "^1.1.0", "@planetscale/database": "^1.8.0", diff --git a/examples/src/agents/discord.ts b/examples/src/agents/discord.ts index 4de1f8b2300d..658c0b6a86db 100644 --- a/examples/src/agents/discord.ts +++ b/examples/src/agents/discord.ts @@ -1,7 +1,7 @@ import { ChatOpenAI } from "langchain/chat_models/openai"; import { initializeAgentExecutorWithOptions } from "langchain/agents"; -import { DiscordSendMessagesTool } from "langchain/tools/discord"; import { DadJokeAPI } from "langchain/tools"; +import { DiscordSendMessagesTool } from "@langchain/community/tools/discord"; const model = new ChatOpenAI({ temperature: 0, diff --git a/examples/src/tools/discord.ts b/examples/src/tools/discord.ts index 30155f3da6e9..b54e0046adc8 100644 --- a/examples/src/tools/discord.ts +++ b/examples/src/tools/discord.ts @@ -4,29 +4,29 @@ import { DiscordSendMessagesTool, DiscordGetGuildsTool, DiscordGetTextChannelsTool, -} from "langchain/tools/discord"; +} from "@langchain/community/tools/discord"; // Get messages from a channel given channel ID const getMessageTool = new DiscordGetMessagesTool(); -const messageResults = await getMessageTool.call("1153400523718938780"); +const messageResults = await getMessageTool.invoke("1153400523718938780"); console.log(messageResults); // Get guilds/servers const getGuildsTool = new DiscordGetGuildsTool(); -const guildResults = await getGuildsTool.call(""); +const guildResults = await getGuildsTool.invoke(""); console.log(guildResults); // Search results in a given channel (case-insensitive) const searchTool = new DiscordChannelSearchTool(); -const searchResults = await searchTool.call("Test"); +const searchResults = await searchTool.invoke("Test"); console.log(searchResults); // Get all text channels of a server const getChannelsTool = new DiscordGetTextChannelsTool(); -const channelResults = await getChannelsTool.call("1153400523718938775"); +const channelResults = await getChannelsTool.invoke("1153400523718938775"); console.log(channelResults); // Send a message const sendMessageTool = new DiscordSendMessagesTool(); -const sendMessageResults = await sendMessageTool.call("test message"); +const sendMessageResults = await sendMessageTool.invoke("test message"); console.log(sendMessageResults); diff --git a/langchain/.gitignore b/langchain/.gitignore index bd4f290235ed..635d41db8711 100644 --- a/langchain/.gitignore +++ b/langchain/.gitignore @@ -61,9 +61,6 @@ 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/connery.cjs tools/connery.js tools/connery.d.ts diff --git a/langchain/package.json b/langchain/package.json index 0ec0641d8410..51716fa93ec5 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -73,9 +73,6 @@ "tools/calculator.cjs", "tools/calculator.js", "tools/calculator.d.ts", - "tools/discord.cjs", - "tools/discord.js", - "tools/discord.d.ts", "tools/connery.cjs", "tools/connery.js", "tools/connery.d.ts", @@ -924,7 +921,6 @@ "chromadb": "^1.5.3", "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", @@ -993,7 +989,6 @@ "chromadb": "*", "convex": "^1.3.1", "d3-dsv": "^2.0.0", - "discord.js": "^14.14.1", "epub2": "^3.0.1", "fast-xml-parser": "^4.2.7", "google-auth-library": "^8.9.0", @@ -1324,11 +1319,6 @@ "import": "./tools/calculator.js", "require": "./tools/calculator.cjs" }, - "./tools/discord": { - "types": "./tools/discord.d.ts", - "import": "./tools/discord.js", - "require": "./tools/discord.cjs" - }, "./tools/connery": { "types": "./tools/connery.d.ts", "import": "./tools/connery.js", diff --git a/langchain/scripts/create-entrypoints.js b/langchain/scripts/create-entrypoints.js index 2a534cf7b285..e5bb0b7c3b2e 100644 --- a/langchain/scripts/create-entrypoints.js +++ b/langchain/scripts/create-entrypoints.js @@ -34,7 +34,6 @@ const entrypoints = { "tools/aws_lambda": "tools/aws_lambda", "tools/aws_sfn": "tools/aws_sfn", "tools/calculator": "tools/calculator", - "tools/discord": "tools/discord", "tools/connery": "tools/connery", "tools/render": "tools/render", "tools/sql": "tools/sql", @@ -356,7 +355,6 @@ const requiresOptionalDependency = [ "tools/aws_lambda", "tools/aws_sfn", "tools/calculator", - "tools/discord", "tools/sql", "tools/webbrowser", "tools/google_calendar", diff --git a/langchain/src/agents/tests/discord.int.test.ts b/langchain/src/agents/tests/discord.int.test.ts deleted file mode 100644 index 8ee54fb262bf..000000000000 --- a/langchain/src/agents/tests/discord.int.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { test } from "@jest/globals"; -import { ChatOpenAI } from "../../chat_models/openai.js"; -import { initializeAgentExecutorWithOptions } from "../../agents/index.js"; -import { DiscordSendMessagesTool } from "../../tools/discord.js"; -import { DadJokeAPI } from "../../tools/dadjokeapi.js"; - -test("DiscordSendMessagesTool should tell a joke in the discord channel", async () => { - const model = new ChatOpenAI({ - temperature: 0, - }); - - const tools = [new DiscordSendMessagesTool(), new DadJokeAPI()]; - - const executor = await initializeAgentExecutorWithOptions(tools, model, { - agentType: "zero-shot-react-description", - verbose: true, - }); - - const res = await executor.invoke({ - input: `Tell a joke in the discord channel`, - }); - - console.log(res.output); -}); diff --git a/langchain/src/load/import_constants.ts b/langchain/src/load/import_constants.ts index 6c108ce0862e..d45a9c6d6227 100644 --- a/langchain/src/load/import_constants.ts +++ b/langchain/src/load/import_constants.ts @@ -7,7 +7,6 @@ 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/gmail", diff --git a/langchain/src/load/import_type.d.ts b/langchain/src/load/import_type.d.ts index 23fdacd69b1a..050171f77ecd 100644 --- a/langchain/src/load/import_type.d.ts +++ b/langchain/src/load/import_type.d.ts @@ -19,9 +19,6 @@ 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/langchain/tools/discord.cjs b/langchain/tools/discord.cjs new file mode 100644 index 000000000000..86511a52674b --- /dev/null +++ b/langchain/tools/discord.cjs @@ -0,0 +1 @@ +module.exports = require('../dist/tools/discord.cjs'); \ No newline at end of file diff --git a/langchain/tools/discord.d.ts b/langchain/tools/discord.d.ts new file mode 100644 index 000000000000..99462973770a --- /dev/null +++ b/langchain/tools/discord.d.ts @@ -0,0 +1 @@ +export * from '../dist/tools/discord.js' \ No newline at end of file diff --git a/langchain/tools/discord.js b/langchain/tools/discord.js new file mode 100644 index 000000000000..99462973770a --- /dev/null +++ b/langchain/tools/discord.js @@ -0,0 +1 @@ +export * from '../dist/tools/discord.js' \ No newline at end of file diff --git a/libs/langchain-community/.gitignore b/libs/langchain-community/.gitignore index 9475e00e7a15..d75f046e3e6b 100644 --- a/libs/langchain-community/.gitignore +++ b/libs/langchain-community/.gitignore @@ -25,6 +25,9 @@ tools/connery.d.ts tools/dadjokeapi.cjs tools/dadjokeapi.js tools/dadjokeapi.d.ts +tools/discord.cjs +tools/discord.js +tools/discord.d.ts tools/dynamic.cjs tools/dynamic.js tools/dynamic.d.ts diff --git a/libs/langchain-community/package.json b/libs/langchain-community/package.json index ed71a2c5fc58..db759ede4a22 100644 --- a/libs/langchain-community/package.json +++ b/libs/langchain-community/package.json @@ -109,6 +109,7 @@ "closevector-web": "0.1.0-alpha.15", "cohere-ai": ">=6.0.0", "convex": "^1.3.1", + "discord.js": "^14.14.1", "dotenv": "^16.0.3", "dpdm": "^3.12.0", "eslint": "^8.33.0", @@ -203,6 +204,7 @@ "closevector-web": "0.1.0-alpha.16", "cohere-ai": ">=6.0.0", "convex": "^1.3.1", + "discord.js": "^14.14.1", "faiss-node": "^0.5.1", "firebase-admin": "^11.9.0", "google-auth-library": "^8.9.0", @@ -377,6 +379,9 @@ "convex": { "optional": true }, + "discord.js": { + "optional": true + }, "faiss-node": { "optional": true }, @@ -511,6 +516,11 @@ "import": "./tools/dadjokeapi.js", "require": "./tools/dadjokeapi.cjs" }, + "./tools/discord": { + "types": "./tools/discord.d.ts", + "import": "./tools/discord.js", + "require": "./tools/discord.cjs" + }, "./tools/dynamic": { "types": "./tools/dynamic.d.ts", "import": "./tools/dynamic.js", @@ -1242,6 +1252,9 @@ "tools/dadjokeapi.cjs", "tools/dadjokeapi.js", "tools/dadjokeapi.d.ts", + "tools/discord.cjs", + "tools/discord.js", + "tools/discord.d.ts", "tools/dynamic.cjs", "tools/dynamic.js", "tools/dynamic.d.ts", diff --git a/libs/langchain-community/scripts/check-tree-shaking.js b/libs/langchain-community/scripts/check-tree-shaking.js index 62f289fd855e..1113cfd15f88 100644 --- a/libs/langchain-community/scripts/check-tree-shaking.js +++ b/libs/langchain-community/scripts/check-tree-shaking.js @@ -31,6 +31,7 @@ export function listExternals() { "convex/server", "convex/values", "@rockset/client/dist/codegen/api.js", + "discord.js", "mysql2/promise", "web-auth-library/google", "firebase-admin/app", diff --git a/libs/langchain-community/scripts/create-entrypoints.js b/libs/langchain-community/scripts/create-entrypoints.js index 0a75fbb878eb..31af551dccc3 100644 --- a/libs/langchain-community/scripts/create-entrypoints.js +++ b/libs/langchain-community/scripts/create-entrypoints.js @@ -18,6 +18,7 @@ const entrypoints = { "tools/brave_search": "tools/brave_search", "tools/connery": "tools/connery", "tools/dadjokeapi": "tools/dadjokeapi", + "tools/discord": "tools/discord", "tools/dynamic": "tools/dynamic", "tools/dataforseo_api_search": "tools/dataforseo_api_search", "tools/gmail": "tools/gmail/index", @@ -184,6 +185,7 @@ const deprecatedNodeOnly = []; const requiresOptionalDependency = [ "tools/aws_sfn", "tools/aws_lambda", + "tools/discord", "tools/gmail", "agents/toolkits/aws_sfn", "callbacks/handlers/llmonitor", diff --git a/libs/langchain-community/src/load/import_constants.ts b/libs/langchain-community/src/load/import_constants.ts index 943495e663dd..af67bd760f43 100644 --- a/libs/langchain-community/src/load/import_constants.ts +++ b/libs/langchain-community/src/load/import_constants.ts @@ -3,6 +3,7 @@ export const optionalImportEntrypoints = [ "langchain_community/tools/aws_lambda", "langchain_community/tools/aws_sfn", + "langchain_community/tools/discord", "langchain_community/tools/gmail", "langchain_community/agents/toolkits/aws_sfn", "langchain_community/embeddings/bedrock", diff --git a/libs/langchain-community/src/load/import_type.d.ts b/libs/langchain-community/src/load/import_type.d.ts index 5d226c55af0a..59e74243194e 100644 --- a/libs/langchain-community/src/load/import_type.d.ts +++ b/libs/langchain-community/src/load/import_type.d.ts @@ -7,6 +7,9 @@ export interface OptionalImportMap { "@langchain/community/tools/aws_sfn"?: | typeof import("../tools/aws_sfn.js") | Promise; + "@langchain/community/tools/discord"?: + | typeof import("../tools/discord.js") + | Promise; "@langchain/community/tools/gmail"?: | typeof import("../tools/gmail/index.js") | Promise; diff --git a/langchain/src/tools/discord.ts b/libs/langchain-community/src/tools/discord.ts similarity index 98% rename from langchain/src/tools/discord.ts rename to libs/langchain-community/src/tools/discord.ts index 40f237377727..b34e6b385fb2 100644 --- a/langchain/src/tools/discord.ts +++ b/libs/langchain-community/src/tools/discord.ts @@ -5,8 +5,8 @@ import { Message, ChannelType, } from "discord.js"; -import { getEnvironmentVariable } from "../util/env.js"; -import { Tool } from "./base.js"; +import { getEnvironmentVariable } from "@langchain/core/utils/env"; +import { Tool } from "@langchain/core/tools"; /** * Base tool parameters for the Discord tools diff --git a/langchain/src/tools/tests/discord.int.test.ts b/libs/langchain-community/src/tools/tests/discord.int.test.ts similarity index 86% rename from langchain/src/tools/tests/discord.int.test.ts rename to libs/langchain-community/src/tools/tests/discord.int.test.ts index feee6e22bb2e..b8920e7c5809 100644 --- a/langchain/src/tools/tests/discord.int.test.ts +++ b/libs/langchain-community/src/tools/tests/discord.int.test.ts @@ -7,7 +7,7 @@ import { DiscordGetTextChannelsTool, } from "../discord.js"; -test("DiscordGetMessagesTool", async () => { +test.skip("DiscordGetMessagesTool", async () => { const tool = new DiscordGetMessagesTool(); try { @@ -21,7 +21,7 @@ test("DiscordGetMessagesTool", async () => { } }); -test("DiscordGetGuildsTool", async () => { +test.skip("DiscordGetGuildsTool", async () => { const tool = new DiscordGetGuildsTool(); try { const result = await tool.invoke(""); @@ -33,7 +33,7 @@ test("DiscordGetGuildsTool", async () => { } }); -test("DiscordChannelSearchTool", async () => { +test.skip("DiscordChannelSearchTool", async () => { const tool = new DiscordChannelSearchTool(); try { const result = await tool.invoke("Test"); @@ -45,7 +45,7 @@ test("DiscordChannelSearchTool", async () => { } }); -test("DiscordGetTextChannelsTool", async () => { +test.skip("DiscordGetTextChannelsTool", async () => { const tool = new DiscordGetTextChannelsTool(); try { const result = await tool.invoke("1153400523718938775"); @@ -57,7 +57,7 @@ test("DiscordGetTextChannelsTool", async () => { } }); -test("DiscordSendMessagesTool", async () => { +test.skip("DiscordSendMessagesTool", async () => { const tool = new DiscordSendMessagesTool(); try { const result = await tool.invoke("test message from new code"); diff --git a/yarn.lock b/yarn.lock index b4fe8a4f75a4..56a120e6fc98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8083,7 +8083,7 @@ __metadata: languageName: unknown linkType: soft -"@langchain/community@workspace:libs/langchain-community, @langchain/community@~0.0.3": +"@langchain/community@workspace:*, @langchain/community@workspace:libs/langchain-community, @langchain/community@~0.0.3": version: 0.0.0-use.local resolution: "@langchain/community@workspace:libs/langchain-community" dependencies: @@ -8156,6 +8156,7 @@ __metadata: closevector-web: 0.1.0-alpha.15 cohere-ai: ">=6.0.0" convex: ^1.3.1 + discord.js: ^14.14.1 dotenv: ^16.0.3 dpdm: ^3.12.0 eslint: ^8.33.0 @@ -8253,6 +8254,7 @@ __metadata: closevector-web: 0.1.0-alpha.16 cohere-ai: ">=6.0.0" convex: ^1.3.1 + discord.js: ^14.14.1 faiss-node: ^0.5.1 firebase-admin: ^11.9.0 google-auth-library: ^8.9.0 @@ -8378,6 +8380,8 @@ __metadata: optional: true convex: optional: true + discord.js: + optional: true faiss-node: optional: true firebase-admin: @@ -18606,6 +18610,7 @@ __metadata: "@getmetal/metal-sdk": ^4.0.0 "@getzep/zep-js": ^0.9.0 "@gomomento/sdk": ^1.51.1 + "@langchain/community": "workspace:*" "@opensearch-project/opensearch": ^2.2.0 "@pinecone-database/pinecone": ^1.1.0 "@planetscale/database": ^1.8.0 @@ -23187,7 +23192,6 @@ __metadata: chromadb: ^1.5.3 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 @@ -23268,7 +23272,6 @@ __metadata: chromadb: "*" convex: ^1.3.1 d3-dsv: ^2.0.0 - discord.js: ^14.14.1 epub2: ^3.0.1 fast-xml-parser: ^4.2.7 google-auth-library: ^8.9.0 From 71e1fa8982abe60ac2c2016e2822a88efe7458fc Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Tue, 12 Dec 2023 12:30:20 -0800 Subject: [PATCH 17/18] Remove build artifacts --- langchain/.env.example | 2 -- langchain/package.json | 3 --- langchain/tools/discord.cjs | 1 - langchain/tools/discord.d.ts | 1 - langchain/tools/discord.js | 1 - 5 files changed, 8 deletions(-) delete mode 100644 langchain/tools/discord.cjs delete mode 100644 langchain/tools/discord.d.ts delete mode 100644 langchain/tools/discord.js diff --git a/langchain/.env.example b/langchain/.env.example index ac2c2e50a304..aa7c2994e9a8 100644 --- a/langchain/.env.example +++ b/langchain/.env.example @@ -16,8 +16,6 @@ AZURE_OPENAI_BASE_PATH=ADD_YOURS_HERE CONNERY_RUNNER_URL=ADD_YOURS_HERE CONNERY_RUNNER_API_KEY=ADD_YOURS_HERE CONVEX_URL=ADD_YOURS_HERE -DISCORD_BOT_TOKEN=ADD_YOURS_HERE -DISCORD_CHANNEL_ID=ADD_YOURS_HERE ELASTIC_URL=http://127.0.0.1:9200 OPENSEARCH_URL=http://127.0.0.1:9200 PINECONE_API_KEY=ADD_YOURS_HERE diff --git a/langchain/package.json b/langchain/package.json index 51716fa93ec5..461c08488333 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -1085,9 +1085,6 @@ "d3-dsv": { "optional": true }, - "discord.js": { - "optional": true - }, "epub2": { "optional": true }, diff --git a/langchain/tools/discord.cjs b/langchain/tools/discord.cjs deleted file mode 100644 index 86511a52674b..000000000000 --- a/langchain/tools/discord.cjs +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('../dist/tools/discord.cjs'); \ No newline at end of file diff --git a/langchain/tools/discord.d.ts b/langchain/tools/discord.d.ts deleted file mode 100644 index 99462973770a..000000000000 --- a/langchain/tools/discord.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '../dist/tools/discord.js' \ No newline at end of file diff --git a/langchain/tools/discord.js b/langchain/tools/discord.js deleted file mode 100644 index 99462973770a..000000000000 --- a/langchain/tools/discord.js +++ /dev/null @@ -1 +0,0 @@ -export * from '../dist/tools/discord.js' \ No newline at end of file From 742526f68fa9a99ebbf9c8d926c8cdfd076787c5 Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Tue, 12 Dec 2023 12:33:19 -0800 Subject: [PATCH 18/18] Update lock --- yarn.lock | 2 -- 1 file changed, 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 56a120e6fc98..4fd4df433a22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23345,8 +23345,6 @@ __metadata: optional: true d3-dsv: optional: true - discord.js: - optional: true epub2: optional: true faiss-node: