Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v10.16 #1074

Merged
merged 28 commits into from
Oct 6, 2024
Merged

v10.16 #1074

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
eb7f89f
commands(select-roles-update): implement roles update
iamtraction Sep 28, 2024
d62b072
version: 10.16.0
iamtraction Sep 28, 2024
aeae60f
deps: update
iamtraction Sep 28, 2024
e054571
settings: update example
iamtraction Sep 28, 2024
6bda47d
eslint: upgrade to v9
iamtraction Sep 28, 2024
2b9f227
eslint: remove old config
iamtraction Sep 28, 2024
b427194
eslint(config): add new config
iamtraction Sep 28, 2024
0a352be
chore: linting
iamtraction Sep 28, 2024
ee1d92c
workflows(nodejs): use node 20.x
iamtraction Sep 28, 2024
611b00a
deps: update tesseract
iamtraction Sep 28, 2024
195880d
listeners(messageDeleteBulk): update typings
iamtraction Sep 28, 2024
d641f80
deps: update
iamtraction Oct 6, 2024
ecc7906
chore: linting
iamtraction Oct 6, 2024
40493e1
deps: add google gen ai lib
iamtraction Oct 6, 2024
c4f63b1
types: add typings for gemini settings
iamtraction Oct 6, 2024
9f0a3cd
settings: update example
iamtraction Oct 6, 2024
b300490
commands(chat): implement gemini support
iamtraction Oct 6, 2024
80f562a
deps: add anthropic sdk
iamtraction Oct 6, 2024
5f1e1f2
types: add typings for anthropic settings
iamtraction Oct 6, 2024
84893e1
settings: update example
iamtraction Oct 6, 2024
3fcb610
commands(chat): implement claude support
iamtraction Oct 6, 2024
8a9690f
commands(chat): update description
iamtraction Oct 6, 2024
4ab51a2
chore: generate command descriptions
iamtraction Oct 6, 2024
db1da65
commands(chat): add user metadata
iamtraction Oct 6, 2024
1191a9f
commands(translate): add metadata
iamtraction Oct 6, 2024
16cf016
actions: add Translate context menu command
iamtraction Oct 6, 2024
412fa90
actions: add Sentiment command
iamtraction Oct 6, 2024
66d8955
chore: generate commands data
iamtraction Oct 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 0 additions & 30 deletions .eslintrc.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

strategy:
matrix:
node-version: [ 18.x ]
node-version: [ 20.x ]

steps:
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion commands.json

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";

export default tseslint.config({
extends: [
eslint.configs.recommended,
...tseslint.configs.recommended,
],
languageOptions: {
parser: tseslint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
sourceType: "module",
},
files: [ "src/**/*.ts" ],
rules: {
indent: [ "warn", 4 ],
"linebreak-style": [ "warn", "unix" ],
quotes: [ "warn", "double" ],
semi: [ "warn", "always" ],
"@typescript-eslint/no-namespace": "off",
},
});
37 changes: 19 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bastion",
"version": "10.15.1",
"version": "10.16.0",
"description": "Get an enhanced Discord experience!",
"type": "module",
"homepage": "https://bastion.traction.one",
Expand All @@ -15,35 +15,36 @@
"commands": "tesseract publish",
"migrate": "node ./dist/migrate.js",
"start": "node .",
"test": "eslint src --ext .ts"
"test": "eslint ."
},
"devDependencies": {
"@types/discord-rpc": "^4.0.8",
"@types/express": "^4.17.21",
"@types/gamedig": "^5.0.2",
"@types/gamedig": "^5.0.3",
"@types/http-errors": "^2.0.4",
"@types/jsdom": "^21.1.6",
"@types/node": "^20.12.12",
"@typescript-eslint/eslint-plugin": "^7.9.0",
"@typescript-eslint/parser": "^7.9.0",
"eslint": "^8.57.0",
"typescript": "^5.4.5"
"@types/jsdom": "^21.1.7",
"@types/node": "^22.7.4",
"eslint": "^9.12.0",
"typescript": "^5.6.2",
"typescript-eslint": "^8.8.0"
},
"dependencies": {
"@bastion/tesseract": "^5.2.0",
"@anthropic-ai/sdk": "^0.28.0",
"@bastion/tesseract": "^5.2.2",
"@discordjs/opus": "^0.9.0",
"@google/generative-ai": "^0.21.0",
"@iamtraction/google-translate": "^2.0.1",
"@iamtraction/play-dl": "^1.9.8",
"discord-rpc": "^4.0.1",
"dotenv": "^16.3.1",
"emoji-regex": "^10.3.0",
"gamedig": "^5.0.0",
"jsdom": "^24.0.0",
"libsodium-wrappers": "^0.7.13",
"mathjs": "^13.0.0",
"openai": "^4.47.1",
"dotenv": "^16.4.5",
"emoji-regex": "^10.4.0",
"gamedig": "^5.1.3",
"jsdom": "^25.0.1",
"libsodium-wrappers": "^0.7.15",
"mathjs": "^13.2.0",
"openai": "^4.67.1",
"r6api.js": "^4.4.1",
"undici": "^6.18.0",
"undici": "^6.19.8",
"ytdl-core": "^4.11.5",
"ytpl": "^2.3.0"
},
Expand Down
27 changes: 25 additions & 2 deletions settings.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,34 @@ nasaApiKey: "DEMO_KEY"
# For more details, check https://openai.com/pricing
openai:
apiKey: ""
# If you want to use GPT-4, set `model` to `gpt-4`.
model: "gpt-3.5-turbo"
# If you want to use GPT-4o, set `model` to `gpt-4o`.
# https://openai.com/api/pricing
model: "gpt-4o-mini"
# Change the `maxTokens` value to set the length of ChatGPT's responses.
# https://platform.openai.com/tokenizer
maxTokens: 100
# Required for `chat` command to use the Google's Gemini APIs.
# API pricing depends on these values.
# For more details, check https://ai.google.dev/pricing
gemini:
apiKey: ""
# If you want to use Gemini 1.5 Pro, set `model` to `gemini-1.5-pro`.
# https://ai.google.dev/gemini-api/docs/models/gemini
model: "gemini-1.5-flash"
# Change the `maxOutputTokens` value to set the length of ChatGPT's responses.
# https://ai.google.dev/gemini-api/docs/tokens
maxOutputTokens: 256
# Required for `chat` command to use the Anthropic's APIs.
# API pricing depends on these values.
# For more details, check https://www.anthropic.com/pricing#anthropic-api
anthropic:
apiKey: ""
# If you want to use Claude 3.5 Sonnet, set `model` to `claude-3-5-sonnet-20240620`.
# https://docs.anthropic.com/en/docs/about-claude/models
model: "claude-3-haiku-20240307"
# Change the `maxTokens` value to set the length of Claude's responses.
# https://docs.anthropic.com/en/docs/about-claude/models#model-comparison-table
maxTokens: 128
# Required for `weather` command.
openWeatherMapApiKey: ""
# Required for `movie` and `tv` commands.
Expand Down
110 changes: 110 additions & 0 deletions src/actions/Sentiment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*!
* @author TRACTION (iamtraction)
* @copyright 2024
*/
import { ApplicationCommandType, MessageContextMenuCommandInteraction } from "discord.js";
import { Client, Command } from "@bastion/tesseract";
import Anthropic from "@anthropic-ai/sdk";
import OpenAI from "openai";
import { GoogleGenerativeAI } from "@google/generative-ai";

import Settings from "../utils/settings.js";

class SentimentCommand extends Command {
constructor() {
super({
type: ApplicationCommandType.Message,
name: "Sentiment",
description: "",
owner: true,
});
}

public async exec(interaction: MessageContextMenuCommandInteraction<"cached">): Promise<unknown> {
if (!interaction.targetMessage.content) return;

const systemPrompt = "You are a helpful and informative AI assistant. You will analyze the given text and provide an assessment of its sentiment. Consider the overall tone, specific words and phrases used, and any contextual clues. Your response should be short, concise, objective, and informative.";
const sentimentPrompt = `Please analyze the following text and provide a assessment of its sentiment: ${ interaction.targetMessage.content }`;

// use ChatGPT if OpenAI API key is present
if (((interaction.client as Client).settings as Settings).get("openai").apiKey) {
const openai = new OpenAI({
apiKey: ((interaction.client as Client).settings as Settings).get("openai").apiKey,
});

const response = await openai.chat.completions.create({
model: ((interaction.client as Client).settings as Settings).get("openai").model,
messages: [
{
role: "system",
content: systemPrompt,
},
{
role: "user",
content: sentimentPrompt,
},
],
max_tokens: ((interaction.client as Client).settings as Settings).get("openai").maxTokens,
user: interaction.member.id,
});

return await interaction.reply({
content: response.choices[0].message.content,
ephemeral: true,
});
}

// use Gemini if Gemini API key is present
if (((interaction.client as Client).settings as Settings).get("gemini").apiKey) {
const gemini = new GoogleGenerativeAI(((interaction.client as Client).settings as Settings).get("gemini").apiKey);
const geminiModel = gemini.getGenerativeModel({
model: ((interaction.client as Client).settings as Settings).get("gemini").model,
systemInstruction: systemPrompt,
generationConfig: {
maxOutputTokens: ((interaction.client as Client).settings as Settings).get("gemini").maxOutputTokens,
},
});

const result = await geminiModel.generateContent(sentimentPrompt);

return await interaction.reply({
content: result.response.text(),
ephemeral: true,
});
}

// use Claude if Anthropic API key is present
if (((interaction.client as Client).settings as Settings).get("anthropic").apiKey) {
const anthropic = new Anthropic({
apiKey: ((interaction.client as Client).settings as Settings).get("anthropic").apiKey,
});

const result = await anthropic.messages.create({
model: ((interaction.client as Client).settings as Settings).get("anthropic").model,
system: systemPrompt,
max_tokens: ((interaction.client as Client).settings as Settings).get("anthropic").maxTokens,
messages: [
{
role: "user",
content: [
{
type: "text",
text: sentimentPrompt,
},
],
},
],
metadata: {
user_id: interaction.member.id,
},
});

return await interaction.reply({
content: result.content[0].type === "text" && result.content[0].text,
ephemeral: true,
});
}
}
}

export { SentimentCommand as Command };
32 changes: 32 additions & 0 deletions src/actions/Translate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*!
* @author TRACTION (iamtraction)
* @copyright 2024
*/
import { ApplicationCommandType, MessageContextMenuCommandInteraction } from "discord.js";
import { Command } from "@bastion/tesseract";
// eslint-disable-next-line @typescript-eslint/no-require-imports
import translate = require("@iamtraction/google-translate");

class TranslateCommand extends Command {
constructor() {
super({
type: ApplicationCommandType.Message,
name: "Translate",
description: "",
});
}

public async exec(interaction: MessageContextMenuCommandInteraction<"cached">): Promise<unknown> {
if (!interaction.targetMessage.content) return;

// fetch the translation
const response = await translate(interaction.targetMessage.content, { to: "en" });

return await interaction.reply({
content: `${ response.text }
-# Translated from ${ response.from.language.iso?.toUpperCase() } to English`,
});
}
}

export { TranslateCommand as Command };
Loading
Loading