Required environmental variables

June 14, 2026 ยท View on GitHub

VariableType of Value
DISCORD_AUTHDiscord Bot Authentication Token
BOT_OWNER_DISCORD_IDDiscord User ID for Bot Owner
BOT_NAMEName the bot will use as username, nickname, and prefix for data files
(NB: Avoid using non-ascii characters to prevent unexpected behavior)
NODE_ENVNode Environment: "production" or "development"

Optional environmental variables

VariableType of Value
DATA_DIROptional absolute or project-relative override for the bot data directory (defaults to ./data).
AMBIENT_BOT_NAME_TRIGGERToggle ambient name-based replies in non-DM channels (true/1 by default, set false/0 to disable).
TOPIC_MEMORY_SALTSalt used to anonymize user IDs in temporal topic memory; if unset, topic memory is disabled (fail-closed).
TRACE_SURPRISEEnable debug traces for surprise-based next/previous token selection in response generation (true/1).
HARNESS_PROXY_ENABLEDEnable local harness HTTP proxy endpoints (true/1 to enable).
HARNESS_PROXY_TOKENBearer token required by harness proxy when enabled.
HARNESS_PROXY_ALLOW_PRODAllow harness proxy in production (false by default).
HARNESS_PROXY_ALLOW_REMOTEAllow non-localhost access to harness proxy (false by default).
HARNESS_PROXY_IP_ALLOWLISTOptional comma-separated source IP allowlist for harness proxy when remote access is enabled.
HARNESS_PROXY_MAX_BODY_BYTESMaximum request payload size accepted by harness proxy (default 1048576).
HARNESS_PROXY_RATE_LIMIT_MAX_REQUESTSMaximum requests per source IP per rate-limit window (default 120).
HARNESS_PROXY_RATE_LIMIT_WINDOW_MSRate-limit window size in milliseconds (default 60000).
HARNESS_PROXY_TRUST_CALLER_ROLESTrust caller-provided isAdmin/isBotOwner flags in harness payloads (default false).

Bot settings

Default bot settings are stored in the resources/default-settings.json file. These should be copied to resources/{bot name}-settings.json.

The following are the required values for the bot settings:

ValueAcceptable RangeDefault ValueDescription
outburstThreshold0.0 - 1.00.005Chance that the bot will respond without being explicitly triggered
angerLevel0.01 - 10.00.5Chance that the bot will yell. Values above 1.0 will cause the bot to always yell
surprise0.0 - 1.00.25Randomness factor for weighted next/previous token selection
angerIncrease0.01 - 10.01.75Value that the angerLevel will be multiplied by if the bot witnesses yelling (all capitalized input)
angerDecrease0.01 - 10.00.8Value that the AngerLevel will be multipled by if the bot does not witness yelling
recursion1 - 51Number of response-generation passes before the final output is chosen
topicMemoryTtlMinutes1 - 144020Minutes a remembered topic stays active for a user+channel
topicMemoryMaxInteractions1 - 10008Maximum number of personality-response generations before topic memory expires
topicMemoryBiasStrength0.0 - 1.00.8Multiplier applied to remembered topic weights when they are overlaid onto response generation
topicMemoryKeywordCount1 - 53Number of ranked keywords extracted from user input when refreshing topic memory
learnFromBotstrue / falsefalseWhether the bot will learn from other bots, or ignore them

Validation

  • npm run build compiles TypeScript into dist/.
  • npm run dev builds and starts the bot locally.
  • npm run start starts from an existing dist/ build.

Note: this branch does not currently define npm test, test:*, or lint scripts.

Steps to deploy initially (no pretrained brain) without git

  1. Copy the following files and directories:
    • ./resources/*
    • ./src/*
    • ./tools/* (NOTE: you should also run chmod +x ./tools/* for the scripts to properly execute)
    • ./Dockerfile
    • ./docker-compose.yml
    • ./package.json
    • ./tsconfig.json
    • ./README.md
    • ./.gitattributes
    • ./.dockerignore
  2. Create the following files and directories:
    • ./.env (See Required environment variables)
    • ./data/
    • (Optional) ./resources/{bot-name}-settings.json (See Bot settings)
    • (Optional) ./resources/{bot-name}-trainer.{txt|json} (See Example trainer schema
      • You can also create a default trainer by running the following commands:
        • cd ./tools/
        • ./generate-trainer.sh
      • This will create the file ./resources/default-trainer.txt based off of data from the ConvAI2 competition
      • WARNING: This requires the curl and jq programs to be installed
  3. Install dependencies via npm:
    • npm install
  4. Build a distribution version of the source:
    • npm run build
    • docker-compose build
  5. Run docker-compose as a daemon:
    • docker-compose up -d

Steps to install when using git

  1. Create a directory for the project to exist in:
    • mkdir -p ~/charlies
    • cd ~/charlies
  2. Clone the project: git clone https://github.com/mureni/charlies2.git ~/charlies
  3. Create the following files and directories:
    • ./.env (See Required environment variables)
    • ./data/
    • (Optional) ./resources/{bot-name}-settings.json (See Bot settings)
    • (Optional) ./resources/{bot-name}-trainer.{txt|json} (See Example trainer schema
      • You can also create a default trainer by running the following commands:
        • cd ./tools/
        • ./generate-trainer.sh
      • This will create the file ./resources/default-trainer.txt based off of data from the ConvAI2 competition
      • WARNING: This requires the curl and jq programs to be installed
  4. Install dependencies via npm:
    • npm install
  5. Build a distribution version of the source:
    • npm run build
    • docker-compose build
  6. Run docker-compose as a daemon:
    • docker-compose up -d

Steps to update when using git

  1. Run the update script:
    • ./tools/update.sh
    • Optional: ./tools/update.sh origin private-dev to target a specific remote/branch

The update script, if not present, can be made as follows:

#!/bin/sh
set -eu

if [ -n "${1:-}" ] && [ -n "${2:-}" ]; then
  REMOTE="\$1"
  BRANCH="\$2"
elif [ -n "${1:-}" ]; then
  case "\$1" in
    */*)
      REMOTE="${1%%/*}"
      BRANCH="${1#*/}"
      ;;
    *)
      REMOTE="origin"
      BRANCH="\$1"
      ;;
  esac
else
  UPSTREAM=$(git rev-parse --abbrev-ref --symbolic-full-name "@{u}" 2>/dev/null || true)
  if [ -n "$UPSTREAM" ] && [ "$UPSTREAM" != "@{u}" ]; then
    REMOTE="${UPSTREAM%%/*}"
    BRANCH="${UPSTREAM#*/}"
  else
    REMOTE="origin"
    BRANCH=$(git rev-parse --abbrev-ref HEAD)
  fi
fi

echo "Stopping docker container for charlies..."
docker-compose down
echo "Retrieving most recent code from remote '$REMOTE', branch '$BRANCH'..."
git pull "$REMOTE" "$BRANCH"
echo "Rebuilding charlies docker image as needed..."
docker-compose build
echo "Starting docker container based off of charlies docker image..."
docker-compose up -d

This will pull the most recent code from the remote git repo