Skip to content

Commit

Permalink
v10.16 (#1074)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamtraction authored Oct 6, 2024
2 parents 641aeef + 66d8955 commit cdaa78f
Show file tree
Hide file tree
Showing 15 changed files with 328 additions and 76 deletions.
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

0 comments on commit cdaa78f

Please sign in to comment.