Skip to content

Commit

Permalink
🔧 Documentation and Code Improvement: Add compatibility for environme…
Browse files Browse the repository at this point in the history
…nt variables and implement token hiding

In README.md, added explanations about backword compatibility with environment variables in version 3.0.1. For multi-instance setups, manual configuration in config.yaml is recommended. Also, added an environment variables column to clarify configuration options.

In MultiInstance.mjs and MultiInstance.ts, added a hideTokens function to prevent tokens from being displayed in log outputs, enhancing security. Improved error messages when duplicate bot names are detected.

Updated the version in package.json to 3.1.0 to reflect the addition of new features.
  • Loading branch information
takuya-o committed Dec 30, 2024
1 parent eb33e61 commit a02221d
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 54 deletions.
66 changes: 33 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
> **Note** 👀
> - Configuration methods have changed in version 3.
> - There is no backward compatibility for configurations.
> - You need to manually rewrite environment variables into `config.yaml`.
> - The version 3.0.1 have backward compatibility for enviromnent variables configurations on single instance.
> - Recommend manually rewrite environment variables into `config.yaml` for multi instance.
## Enhanced from the [original yGuy/chatgpt-mattermost-bot](https://github.com/yGuy/chatgpt-mattermost-bot)

Expand Down Expand Up @@ -131,38 +131,38 @@ BOT_INSTRUCTION: "You are a helpful assistant. Whenever users asks you for help
### Configuration Options
| Name | Required | Default Value | Description |
|----------------------|----------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------|
| MATTERMOST_URL | yes | none | The URL to the Mattermost server. This is default for all bots. |
| BOT_CONTEXT_MSG | no | 100 | The number of previous messages which are appended to the conversation with ChatGPT. |
| PLUGINS | no | 'image-plugin graph-plugin' | The enabled plugins of the bot. This is default for all bots. By default, all plugins (graph-plugin and image-plugin) are enabled. |
| OPENAI_MAX_TOKENS | no | 2000 | The maximum number of tokens to pass to the LLM's API. This is default for all bots. |
| OPENAI_TEMPERATURE | no | 1 | The sampling temperature to use, between 0 and 2. Higher values make the output more random, while lower values make it more focused and deterministic. This is default for all bots. |
| MAX_PROMPT_TOKENS | no | 2000 | Maximum number of prompt tokens. This is default for all bots. |
| BOT_INSTRUCTION | no | 'You are a helpful assistant...` | Extra instruction to give your assistance. How should the assistant behave? This setting used by all bots. |
| Name | Required | Default Value | Description | Environment Variables |
|----------------------|----------|---------------|-----------------------------------------------------------------------------------------------------------------------|-----------------------------------------|
| MATTERMOST_URL | yes | none | The URL to the Mattermost server. This is default for all bots. | MATTERMOST_URL |
| BOT_CONTEXT_MSG | no | 100 | The number of previous messages which are appended to the conversation with ChatGPT. | BOT_CONTEXT_MSG |
| PLUGINS | no | 'image-plugin graph-plugin' | The enabled plugins of the bot. This is default for all bots. By default, all bot (graph-plugin and image-plugin) are enabled. | PLUGINS |
| OPENAI_MAX_TOKENS | no | 2000 | The maximum number of tokens to pass to the LLM's API. This is default for all bots. | OPENAI_MAX_TOKENS |
| OPENAI_TEMPERATURE | no | 1 | The sampling temperature to use, between 0 and 2. Higher values make the output more random, while lower values make it more focused and deterministic. This is default for all bots. | OPENAI_TEMPERATURE |
| MAX_PROMPT_TOKENS | no | 2000 | Maximum number of prompt tokens. This is default for all bots. | MAX_PROMPT_TOKENS |
| BOT_INSTRUCTION | no | 'You are a helpful assistant...` | Extra instruction to give your assistance. How should the assistant behave? This setting used by all bots. | BOT_INSTRUCTION |
|
| name | yes | none | The name of the bot. |
| mattermostUrl | no | none | The URL to the Mattermost server for the bot. |
| mattermostToken | yes | none | The authentication token for the Mattermost bot. |
| type | yes | none | The type of AI provider (e.g., openai, azure, google, cohere, anthropic). |
| apiKey | yes | none | The API key for the AI provider. |
| apiBase | no | none | The base URL for the AI provider's API. |
| modelName | no | 'gpt-4o-mini' | The name of the model to use for chat completions. |
| visionModelName | no | none | The name of the model to use for vision tasks. |
| imageModelName | no | none | The name of the model to use for image generation. |
| apiVersion | no | '2024-10-21' | The API version to use for the AI provider. |
| instanceName | no | none | The instance name for the AI provider (specific to Azure). |
| deploymentName | no | none | The deployment name for the AI provider (specific to Azure). |
| visionKey | no | none | The API key for the vision tasks (specific to Azure). |
| visionInstanceName | no | none | The instance name for the vision tasks (specific to Azure). |
| visionDeploymentName | no | none | The deployment name for the vision tasks (specific to Azure). |
| imageKey | no | none | The API key for the image generation tasks (specific to Azure). |
| imageInstanceName | no | none | The instance name for the image generation tasks (specific to Azure). |
| imageDeploymentName | no | none | The deployment name for the image generation tasks (specific to Azure). |
| maxTokens | no | 2000 | The maximum number of tokens for the AI provider. |
| temperature | no | 1 | The sampling temperature for the AI provider. |
| maxPromptTokens | no | 2000 | The maximum number of prompt tokens for the AI provider. |
| plugins | no | 'image-plugin graph-plugin' | The enabled plugins for the bot. |
| name | yes | none | The name of the bot. | |
| mattermostUrl | no | none | The URL to the Mattermost server for the bot. | MATTERMOST_URL |
| mattermostToken | yes | none | The authentication token for the Mattermost bot. | \${name}_MATTERMOST_TOKEN, \${type}_MATTERMOST_TOKEN, MATTERMOST_TOKEN |
| type | yes | none | The type of AI provider (e.g., openai, azure, google, cohere, anthropic). | |
| apiKey | yes | none | The API key for the AI provider. | OPENAI_API_KEY, AZURE_OPENAI_API_KEY, GOOGLE_API_KEY, COHERE_API_KEY, ANTHROPIC_API_KEY |
| apiBase | no | none | The base URL for the AI provider's API. | OPENAI_API_BASE |
| modelName | no | 'gpt-4o-mini' | The name of the model to use for chat completions. | OPENAI_MODEL_NAME |
| visionModelName | no | none | The name of the model to use for vision tasks. | |
| imageModelName | no | none | The name of the model to use for image generation. | |
| apiVersion | no | '2024-10-21' | The API version to use for the AI provider. | AZURE_OPENAI_API_VERSION |
| instanceName | no | none | The instance name for the AI provider (specific to Azure). | AZURE_OPENAI_API_INSTANCE_NAME |
| deploymentName | no | none | The deployment name for the AI provider (specific to Azure). | AZURE_OPENAI_API_DEPLOYMENT_NAME |
| visionKey | no | none | The API key for the vision tasks (specific to Azure). | AZURE_OPENAI_API_VISION_KEY |
| visionInstanceName | no | none | The instance name for the vision tasks (specific to Azure). | AZURE_OPENAI_API_VISION_INSTANCE_NAME |
| visionDeploymentName | no | none | The deployment name for the vision tasks (specific to Azure). | AZURE_OPENAI_API_VISION_DEPLOYMENT_NAME |
| imageKey | no | none | The API key for the image generation tasks (specific to Azure). | AZURE_OPENAI_API_IMAGE_KEY |
| imageInstanceName | no | none | The instance name for the image generation tasks (specific to Azure). | AZURE_OPENAI_API_IMAGE_INSTANCE_NAME |
| imageDeploymentName | no | none | The deployment name for the image generation tasks (specific to Azure). | AZURE_OPENAI_API_IMAGE_DEPLOYMENT_NAME |
| maxTokens | no | 2000 | The maximum number of tokens for the AI provider. | OPENAI_MAX_TOKENS |
| temperature | no | 1 | The sampling temperature for the AI provider. | OPENAI_TEMPERATURE |
| maxPromptTokens | no | 2000 | The maximum number of prompt tokens for the AI provider. | MAX_PROMPT_TOKENS |
| plugins | no | 'image-plugin graph-plugin' | The enabled plugins for the bot. By default, The bot graph-plugin and image-plugin are enabled. | PLUGINS |

> **Note**
> The `YFILES_SERVER_URL` is used for automatically converting text information created by the bot into diagrams.
Expand Down
30 changes: 21 additions & 9 deletions dist/MultiInstance.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ var BotService2 = class {
* @param height - 画像の高さ(任意)。
* @returns Base64形式の画像データ。
*/
// 画像をBase64形式で取得する
// 画像をBase64形式で取得する //TODO: 関数も、画像の取得と変換を別の関数に分割することが考えられます。
async getBase64Image(url, token = "", format = "", width = 0, height = 0) {
const init = {};
if (token) {
Expand Down Expand Up @@ -2051,17 +2051,15 @@ var OpenAIWrapper = class {
var botServices = {};
async function main() {
const config2 = getConfig();
if (!config2.bots) {
config2.bots = [{}];
}
config2.bots = config2.bots || [{}];
config2.bots.forEach(async (botConfig) => {
const name = botConfig.name ?? process.env["MATTERMOST_BOTNAME"];
if (botServices[name]) {
botLog.error(`Duplicate bot name detected: ${name}. Ignoring this bot configuration.`, botConfig);
botLog.error(`Duplicate bot name detected: ${name}. Ignoring this bot configuration.`, hideTokens(botConfig));
return;
}
if (!name) {
botLog.error("No name. Ignore provider config", botConfig);
botLog.error("No name. Ignore provider config", hideTokens(botConfig));
return;
}
botConfig.name = name;
Expand All @@ -2077,13 +2075,13 @@ async function main() {
} else if (process.env["ANTHROPIC_API_KEY"]) {
botConfig.type = "anthropic";
} else {
botLog.error(`${name} No type. Ignore provider config`, botConfig);
botLog.error(`${name} No type. Ignore provider config`, hideTokens(botConfig));
return;
}
botLog.warn(`${name} No type. Guessing type as ${botConfig.type}.`, botConfig);
botLog.warn(`${name} No type. Guessing type as ${botConfig.type}.`, hideTokens(botConfig));
}
botLog.log(`${name} Connected to Mattermost.`);
const mattermostToken = botConfig.mattermostToken ?? process.env[`${botConfig.type.toUpperCase()}_MATTERMOST_TOKEN`] ?? process.env["MATTERMOST_TOKEN"];
const mattermostToken = botConfig.mattermostToken ?? process.env[`${name.toUpperCase()}_MATTERMOST_TOKEN`] ?? process.env[`${botConfig.type.toUpperCase()}_MATTERMOST_TOKEN`] ?? process.env["MATTERMOST_TOKEN"];
const mattermostClient = new MattermostClient(
botConfig.mattermostUrl ?? config2.MATTERMOST_URL ?? process.env["MATTERMOST_URL"],
mattermostToken
Expand All @@ -2109,6 +2107,20 @@ async function main() {
botLog.trace(`${name} Listening to MM messages...`);
botServices[name] = botService;
});
function hideTokens(botConfig) {
if (botConfig.mattermostToken) {
botConfig.mattermostToken = "***";
}
if (botConfig.apiKey) {
botConfig.apiKey = "***";
}
if (botConfig.imageKey) {
botConfig.imageKey = "***";
}
if (botConfig.visionKey) {
botConfig.visionKey = "***";
}
}
}
main().catch((reason) => {
botLog.error(reason);
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chatgpt-mattermost-bot",
"version": "3.0.0",
"version": "3.1.0",
"description": "ChatGPT bot on mattermost",
"private": true,
"keywords": [
Expand Down
2 changes: 1 addition & 1 deletion src/BotService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export class BotService {
* @param height - 画像の高さ(任意)。
* @returns Base64形式の画像データ。
*/
// 画像をBase64形式で取得する
// 画像をBase64形式で取得する //TODO: 関数も、画像の取得と変換を別の関数に分割することが考えられます。
private async getBase64Image(
url: string,
token: string = '',
Expand Down
34 changes: 27 additions & 7 deletions src/MultiInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@ import { getConfig } from './config'
const botServices: Record<string, BotService> = {}

/* Entry point */
// eslint-disable-next-line max-lines-per-function
async function main(): Promise<void> {
const config = getConfig()
if (!config.bots) {
config.bots = [{}]
}
config.bots = config.bots || [{}] // 旧バージョンの環境変数での設定を期待する
config.bots.forEach(async (botConfig: ProviderConfig) => {
const name = botConfig.name ?? process.env['MATTERMOST_BOTNAME']
if (botServices[name]) {
botLog.error(`Duplicate bot name detected: ${name}. Ignoring this bot configuration.`, botConfig)
botLog.error(`Duplicate bot name detected: ${name}. Ignoring this bot configuration.`, hideTokens(botConfig))
return
}
if (!name) {
botLog.error('No name. Ignore provider config', botConfig)
botLog.error('No name. Ignore provider config', hideTokens(botConfig))
return
}
botConfig.name = name
Expand All @@ -42,15 +41,16 @@ async function main(): Promise<void> {
} else if (process.env['ANTHROPIC_API_KEY']) {
botConfig.type = 'anthropic'
} else {
botLog.error(`${name} No type. Ignore provider config`, botConfig)
botLog.error(`${name} No type. Ignore provider config`, hideTokens(botConfig))
return
}
botLog.warn(`${name} No type. Guessing type as ${botConfig.type}.`, botConfig)
botLog.warn(`${name} No type. Guessing type as ${botConfig.type}.`, hideTokens(botConfig))
}
botLog.log(`${name} Connected to Mattermost.`)
// AZURE_MATTERMOST_TOKEN, GOOGLE_MATTERMOST_TOKEN... を新設
const mattermostToken =
botConfig.mattermostToken ??
process.env[`${name.toUpperCase()}_MATTERMOST_TOKEN`] ??
process.env[`${botConfig.type.toUpperCase()}_MATTERMOST_TOKEN`] ??
process.env['MATTERMOST_TOKEN']
const mattermostClient = new MattermostClient(
Expand Down Expand Up @@ -78,6 +78,26 @@ async function main(): Promise<void> {
botLog.trace(`${name} Listening to MM messages...`)
botServices[name] = botService
})
// if ( Object.keys(botServices).length === 0 ) {
// botLog.error('No bot is configured. Exiting...')
// process.exit(-1)
// }
// botLog.log('All bots started.')

function hideTokens(botConfig: ProviderConfig) {
if (botConfig.mattermostToken) {
botConfig.mattermostToken = '***'
}
if (botConfig.apiKey) {
botConfig.apiKey = '***'
}
if (botConfig.imageKey) {
botConfig.imageKey = '***'
}
if (botConfig.visionKey) {
botConfig.visionKey = '***'
}
}
}

main().catch(reason => {
Expand Down
Loading

0 comments on commit a02221d

Please sign in to comment.