/[sudobot]/branches/7.x/src/commands/fun/AICommand.ts
ViewVC logotype

Contents of /branches/7.x/src/commands/fun/AICommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (show annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months ago) by rakinar2
File MIME type: application/typescript
File size: 6409 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 /**
2 * This file is part of SudoBot.
3 *
4 * Copyright (C) 2021-2023 OSN Developers.
5 *
6 * SudoBot is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * SudoBot is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 import axios from "axios";
21 import { ChatInputCommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js";
22 import Command, { CommandReturn } from "../../core/Command";
23 import { ChatInputCommandContext } from "../../services/CommandManager";
24 import Pagination from "../../utils/Pagination";
25 import { logError } from "../../utils/logger";
26 import { chunkedString } from "../../utils/utils";
27
28 export default class AICommand extends Command {
29 public readonly name = "ai";
30 public readonly permissions = [];
31 public readonly aliases = ["ask"];
32 public readonly supportsLegacy = false;
33 public readonly slashCommandBuilder = new SlashCommandBuilder().addStringOption(option =>
34 option.setName("prompt").setDescription("Ask something").setMaxLength(1000).setRequired(true)
35 );
36 public readonly description = "Ask something to the AI.";
37
38 async execute(interaction: ChatInputCommandInteraction, context: ChatInputCommandContext): Promise<CommandReturn> {
39 await interaction.deferReply();
40
41 const prompt = interaction.options.getString("prompt", true);
42 let content = "";
43
44 try {
45 if (process.env.GOOGLE_MAKERSUIT_KEY) {
46 const url = `https://generativelanguage.googleapis.com/v1beta2/models/chat-bison-001:generateMessage?key=${encodeURIComponent(
47 process.env.GOOGLE_MAKERSUIT_KEY
48 )}`;
49
50 const response = await axios.post(url, {
51 prompt: {
52 messages: [
53 {
54 content: prompt
55 }
56 ],
57 context: "You're SudoBot, a Discord Moderation Bot.",
58 examples: undefined
59 },
60 temperature: undefined,
61 candidate_count: 1,
62 topK: undefined,
63 topP: undefined
64 });
65
66 if (response.data.filters?.[0]?.reason) {
67 const reason =
68 {
69 BLOCKED_REASON_UNSPECIFIED: "for an unspecified reason",
70 SAFETY: "by the safety filter"
71 }[response.data.filters?.[0]?.reason as string] ?? "for unknown reasons";
72
73 await interaction.editReply({
74 content: `This request was cancelled ${reason}.`
75 });
76
77 return;
78 }
79
80 console.log(JSON.stringify(response.data, null, 2));
81
82 content = response.data.candidates?.[0]?.content;
83 } else if (process.env.CF_AI_URL) {
84 const { data } = await axios.post(
85 process.env.CF_AI_URL!,
86 {
87 messages: [
88 {
89 role: "system",
90 content:
91 "You are a Discord Moderation bot. Your name is SudoBot. You were built at OSN, by open source developers."
92 },
93 { role: "user", content: prompt }
94 ]
95 },
96 {
97 headers: {
98 "Content-Type": "application/json"
99 }
100 }
101 );
102
103 console.log(data);
104 content = data.response;
105 } else {
106 await interaction.editReply({
107 content: "No suitable AI service provider was configured."
108 });
109
110 return;
111 }
112
113 const chunks = chunkedString(content);
114
115 if (chunks.length === 1) {
116 await interaction.editReply({
117 embeds: [
118 new EmbedBuilder({
119 title: "Response",
120 color: 0x007bff,
121 description: chunks[0],
122 footer: {
123 text: `Responses will not always be complete or correct`
124 },
125 timestamp: new Date().toISOString()
126 })
127 ]
128 });
129
130 return;
131 }
132
133 const pagination = new Pagination(chunks, {
134 limit: 1,
135 channelId: interaction.channelId!,
136 guildId: interaction.guildId!,
137 client: this.client,
138 embedBuilder({ currentPage, data: [chunk], maxPages }) {
139 return new EmbedBuilder({
140 title: "Response",
141 color: 0x007bff,
142 description: chunk,
143 footer: {
144 text: `Page ${currentPage} of ${maxPages} • Responses will not always be complete or correct`
145 },
146 timestamp: new Date().toISOString()
147 });
148 },
149 timeout: 60_000 * 5
150 });
151
152 const message = await interaction.editReply(await pagination.getMessageOptions(1));
153 await pagination.start(message!);
154 } catch (error) {
155 logError(error);
156
157 await interaction.editReply({
158 content: `${this.emoji("error")} An error has occurred while trying to communicate with the AI model.`
159 });
160
161 return;
162 }
163 }
164 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26