Skip to content

soulshack, an irc chatbot. openai/ollama api compatible. easy shell tooling.

License

Notifications You must be signed in to change notification settings

pkdindustries/soulshack

Repository files navigation

//  ____                    _   ____    _                      _
// / ___|    ___    _   _  | | / ___|  | |__     __ _    ___  | | __
// \___ \   / _ \  | | | | | | \___ \  | '_ \   / _` |  / __| | |/ /
//  ___) | | (_) | | |_| | | |  ___) | | | | | | (_| | | (__  |   <
// |____/   \___/   \__,_| |_| |____/  |_| |_|  \__,_|  \___| |_|\_\
//  .  .  .  because  real  people  are  overrated

soulshack is an irc chat bot that utilizes an openai api endpoint to generate human-like responses.

features

  • connects to an irc server and joins a specified channel
  • utilizes the openai api and compatible endpoints like ollama
  • allows dynamic configuration of bot settings through commands
  • supports ssl and SASL authentication for irc servers
  • tool calling, example tools, channel management tools

building

go build .
docker build . -t soulshack:dev

usage

soulshack --nick chatbot --server irc.freenode.net --port 6697 --channel '#soulshack' --ssl --apikey ****************

configuration

soulshack can be configured using command line flags, environment variables, or configuration files.

flags

Usage:
  soulshack --channel <channel> [--nick <nickname>] [--server <server>] [--port <port>] [--tls] [--apikey <key>] [flags]

Examples:
soulshack --nick chatbot --server irc.freenode.net --port 6697 --channel '#soulshack' --tls --apikey ****************

Flags:
  -a, --addressed                  require bot be addressed by nick for response (default true)
  -A, --admins strings             comma-separated list of allowed hostmasks (e.g. alex!~alex@localhost, josh!~josh@localhost).
  -t, --apitimeout duration        timeout for each completion request (default 5m0s)
  -c, --channel string             irc channel to join
  -C, --chunkdelay duration        after this delay, bot will look to split the incoming buffer on sentence boundaries (default 15s)
  -m, --chunkmax int               maximum number of characters to send as a single message (default 350)
  -b, --config string              use the named configuration file
      --greeting string            prompt to be used when the bot joins the channel (default "hello.")
  -h, --help                       help for soulshack
      --maxtokens int              maximum number of tokens to generate (default 512)
      --model string               model to be used for responses (default "gpt-4o")
  -n, --nick string                bot's nickname on the irc server (default "soulshack")
      --apikey string           openai api key
      --apiurl string           alternative base url to use instead of openai
  -p, --port int                   irc server port (default 6667)
      --prompt string              initial system prompt (default "you are a helpful chatbot. do not use caps. do not use emoji.")
      --saslnick string            nick used for SASL
      --saslpass string            password for SASL plain
  -s, --server string              irc server address (default "localhost")
  -S, --sessionduration duration   duration for the chat session; message context will be cleared after this time (default 3m0s)
  -H, --sessionhistory int         maximum number of lines of context to keep per session (default 50)
      --temperature float32        temperature for the completion (default 0.7)
  -e, --tls                        enable TLS for the IRC connection
      --tlsinsecure                skip TLS certificate verification
      --tools                      enable tool use (default false)
      --toolsdir                   directory to load tools from (default "examples/tools")
      --top_p float32              top P value for the completion (default 1)
  -v, --verbose                    enable verbose logging of sessions and configuration
      --version                    version for soulshack

environment variables

all flags can also be set via environment variables with the prefix soulshack_. for example, soulshack_server for the --server flag.

configuration files

configuration files use the yaml format. they can be loaded using the --config flag. a configuration file can contain any of the settings that can be set via flags.

adding a config

to use create a new configuration file, follow these steps:

  1. create a new yml file with the desired name (e.g., marvin.yml).
  2. add your desired settings to the yml file. for example:
nick: marvin
greeting: "explain the size of your brain compared to common household objects."
prompt: "you are marvin the paranoid android. respond with a short text message: "
channel: "#marvinshouse"
server: localhost
soulshack --config /path/to/marvin.yml 

commands

  • /set: set a configuration parameter (e.g., /set nick newnick)
  • /get: get the current value of a configuration parameter (e.g., /get nick)
  • /leave: make the bot leave the channel and exit
  • /help: display help for available commands

tools

put an executable or script in your tooldir location. in order for it to be registered it must respond to the following commands:

  • --schema: Outputs a JSON schema describing the tool use.
  • --execute $json: Will be called with JSON matching your schema

try to make sure the llm can't inject something in the execute json that will ruin your life. because you can't trust bots or the people who use them.

to be honest you shouldn't do this will shell scripts, it's kind of a minefield. so here's a shell script

set -e

# Check if --schema argument is provided
if [[ "$1" == "--schema" ]]; then
  # Output a JSON schema to describe the tool
  # shellcheck disable=SC2016
  cat <<EOF
  {
  "name": "get_current_date_with_format",
  "description": "provides the current time and date in the specified unix date command format",
  "type": "object",
  "properties": {
    "format": {
      "type": "string",
      "description": "The format for the date. use unix date command format (e.g., +%Y-%m-%d %H:%M:%S). always include the leading + sign."
    }
  },
  "required": ["format"],
  "additionalProperties": false
  }
EOF
  exit 0
fi



if [[ "$1" == "--execute" ]]; then
  # Ensure jq is available
  if ! command -v jq &> /dev/null; then
    echo "Error: jq is not installed." >&2
    exit 1
  fi

  # Extract format field from JSON
  format=$(jq -r '.format' <<< "$2")

  # Sanitize the format string
  if [[ "$format" =~ [^a-zA-Z0-9%+:/\ \-] ]]; then
    echo "Error: Invalid characters in format string." >&2
    exit 1
  fi

  # Use -- to prevent option parsing
  date_output=$(date -- "$format")
  echo "$date_output"
  exit 0
fi


# if no arguments, show usage
# shellcheck disable=SC2140
echo "Usage: currentdate.sh [--schema | --execute '{"format": "+%Y-%m-%d %H:%M:%S"}']"

jacob, high five me

named as tribute to my old friend dayv, sp0t, who i think of often