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..476d44c99172 --- /dev/null +++ b/docs/core_docs/docs/integrations/tools/discord.mdx @@ -0,0 +1,30 @@ +--- +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/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 new file mode 100644 index 000000000000..658c0b6a86db --- /dev/null +++ b/examples/src/agents/discord.ts @@ -0,0 +1,22 @@ +import { ChatOpenAI } from "langchain/chat_models/openai"; +import { initializeAgentExecutorWithOptions } from "langchain/agents"; +import { DadJokeAPI } from "langchain/tools"; +import { DiscordSendMessagesTool } from "@langchain/community/tools/discord"; + +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.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..b54e0046adc8 --- /dev/null +++ b/examples/src/tools/discord.ts @@ -0,0 +1,32 @@ +import { + DiscordGetMessagesTool, + DiscordChannelSearchTool, + DiscordSendMessagesTool, + DiscordGetGuildsTool, + DiscordGetTextChannelsTool, +} from "@langchain/community/tools/discord"; + +// Get messages from a channel given channel ID +const getMessageTool = new DiscordGetMessagesTool(); +const messageResults = await getMessageTool.invoke("1153400523718938780"); +console.log(messageResults); + +// Get guilds/servers +const getGuildsTool = new DiscordGetGuildsTool(); +const guildResults = await getGuildsTool.invoke(""); +console.log(guildResults); + +// Search results in a given channel (case-insensitive) +const searchTool = new DiscordChannelSearchTool(); +const searchResults = await searchTool.invoke("Test"); +console.log(searchResults); + +// Get all text channels of a server +const getChannelsTool = new DiscordGetTextChannelsTool(); +const channelResults = await getChannelsTool.invoke("1153400523718938775"); +console.log(channelResults); + +// Send a message +const sendMessageTool = new DiscordSendMessagesTool(); +const sendMessageResults = await sendMessageTool.invoke("test message"); +console.log(sendMessageResults); 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/libs/langchain-community/src/tools/discord.ts b/libs/langchain-community/src/tools/discord.ts new file mode 100644 index 000000000000..b34e6b385fb2 --- /dev/null +++ b/libs/langchain-community/src/tools/discord.ts @@ -0,0 +1,419 @@ +import { + Client, + TextChannel, + GatewayIntentBits, + Message, + ChannelType, +} from "discord.js"; +import { getEnvironmentVariable } from "@langchain/core/utils/env"; +import { Tool } from "@langchain/core/tools"; + +/** + * Base tool parameters for the Discord tools + */ +interface DiscordToolParams { + botToken?: string; + client?: Client; +} + +/** + * Tool parameters for the DiscordGetMessagesTool + */ +interface DiscordGetMessagesToolParams extends DiscordToolParams { + messageLimit?: number; +} + +/** + * Tool parameters for the DiscordSendMessageTool + */ +interface DiscordSendMessageToolParams extends DiscordToolParams { + channelId?: 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 + * 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; + + protected client: Client; + + constructor(fields?: DiscordGetMessagesToolParams) { + super(); + + const { + botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), + messageLimit = 10, + client, + } = fields ?? {}; + + if (!botToken) { + throw new Error( + "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 { + try { + 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, + }); + await this.client.destroy(); + const results = + messages.map((message: Message) => ({ + author: message.author.tag, + content: message.content, + timestamp: message.createdAt, + })) ?? []; + + return JSON.stringify(results); + } catch (err) { + await this.client.destroy(); + return "Error getting messages."; + } + } +} + +/** + * 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; + + protected client: Client; + + constructor(fields?: DiscordToolParams) { + super(); + + const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), client } = + fields ?? {}; + + if (!botToken) { + throw new Error( + "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 { + try { + await this.client.login(this.botToken); + + 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, + })) ?? []; + + return JSON.stringify(results); + } catch (err) { + await this.client.destroy(); + return "Error getting guilds."; + } + } +} + +/** + * 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; + + protected client: Client; + + constructor(fields?: DiscordToolParams) { + super(); + + const { botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), client } = + fields ?? {}; + + if (!botToken) { + throw new Error( + "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 { + 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(); + + 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."; + } + } +} + +/** + * 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 and channelId 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; + + protected client: Client; + + constructor(fields?: DiscordSendMessageToolParams) { + super(); + + const { + botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), + channelId = getEnvironmentVariable("DISCORD_CHANNEL_ID"), + client, + } = fields ?? {}; + + if (!botToken) { + throw new Error( + "Environment variable DISCORD_BOT_TOKEN missing, but is required for DiscordSendMessagesTool." + ); + } + + if (!channelId) { + throw new Error( + "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; + } + + /** @ignore */ + async _call(message: string): Promise { + try { + await this.client.login(this.botToken); + + const channel = (await this.client.channels.fetch( + this.channelId + )) as TextChannel; + + if (!channel) { + throw new Error("Channel not found"); + } + + if (!(channel.constructor === TextChannel)) { + throw new Error("Channel is not text channel, cannot send message"); + } + + await channel.send(message); + + await this.client.destroy(); + + return "Message sent successfully."; + } 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 + * 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; + + protected client: Client; + + constructor(fields?: DiscordChannelSearchParams) { + super(); + + const { + botToken = getEnvironmentVariable("DISCORD_BOT_TOKEN"), + channelId = getEnvironmentVariable("DISCORD_CHANNEL_ID"), + client, + } = fields ?? {}; + + if (!botToken) { + throw new Error( + "Environment variable DISCORD_BOT_TOKEN missing, but is required for DiscordChannelSearchTool." + ); + } + + if (!channelId) { + throw new Error( + "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; + } + + /** @ignore */ + async _call(searchTerm: string): Promise { + try { + 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(); + 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, + })) ?? []; + + return JSON.stringify(results); + } catch (err) { + await this.client.destroy(); + return "Error searching through channel."; + } + } +} diff --git a/libs/langchain-community/src/tools/tests/discord.int.test.ts b/libs/langchain-community/src/tools/tests/discord.int.test.ts new file mode 100644 index 000000000000..b8920e7c5809 --- /dev/null +++ b/libs/langchain-community/src/tools/tests/discord.int.test.ts @@ -0,0 +1,69 @@ +import { test } from "@jest/globals"; +import { + DiscordGetMessagesTool, + DiscordChannelSearchTool, + DiscordSendMessagesTool, + DiscordGetGuildsTool, + DiscordGetTextChannelsTool, +} from "../discord.js"; + +test.skip("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 () => { + 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 () => { + 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 () => { + 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 () => { + 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); + } +}); diff --git a/yarn.lock b/yarn.lock index f0eabe4b2ddf..4fd4df433a22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6033,6 +6033,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" @@ -7094,6 +7173,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" @@ -7997,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: @@ -8070,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 @@ -8167,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 @@ -8292,6 +8380,8 @@ __metadata: optional: true convex: optional: true + discord.js: + optional: true faiss-node: optional: true firebase-admin: @@ -9401,6 +9491,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" @@ -12365,6 +12479,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" @@ -12383,6 +12506,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" @@ -12842,6 +12974,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" @@ -16772,6 +16911,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" @@ -18442,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 @@ -18705,7 +18874,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 @@ -23653,6 +23822,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" @@ -23889,6 +24065,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" @@ -30645,6 +30828,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" @@ -30680,6 +30870,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" @@ -30694,13 +30891,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" @@ -31273,6 +31463,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" @@ -32611,7 +32810,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.14.2, ws@npm:^8.5.0": +"ws@npm:8.14.2, ws@npm:^8.14.2, ws@npm:^8.5.0": version: 8.14.2 resolution: "ws@npm:8.14.2" peerDependencies: