diff options
Diffstat (limited to '')
-rw-r--r-- | README.md | 220 | ||||
-rw-r--r-- | config-example.toml | 33 | ||||
-rw-r--r-- | docker-compose.yaml | 5 | ||||
-rw-r--r-- | main.go | 39 |
4 files changed, 241 insertions, 56 deletions
@@ -1,7 +1,7 @@ # milla -Milla is an IRC bot that sends things over to an LLM when you ask it questions, prints the answer with syntax-hilighting.<br/> -Currently Supported Models: +Milla is an IRC bot that sends things over to an LLM when you ask it questions and prints the answer with optional syntax-hilighting.<br/> +Currently Supported: - Ollama - Openai @@ -9,38 +9,185 @@ Currently Supported Models: ![milla](./milla.png) -### Config - -config: - -```toml -ircServer = "irc.terminaldweller.com" -ircPort = 6697 -ircNick = "mybot" -ircSaslUser = "mybot" -ircSaslPass = "mypass" -ircChannels = ["#mychannel1", "#mychannel2"] -ollamaEndpoint = "" -temp = 0.2 -ollamaSystem = "" -requestTimeout = 10 -millaReconnectDelay = 60 -enableSasl = true -model = "llama2-uncensored" -chromaStyle = "rose-pine-moon" -chromaFormatter = "terminal256" -provider = "ollama" # ollama, chatgpt, gemini -apikey = "key" -topP = 0.9 -topK = 20 +milla accepts one cli arg which tells it where to look for the config file:<br/> + +```$ milla -help +Usage of ./milla: + -config string + path to the config file (default "./config.toml") +``` + +## Config + +An exhaustive example is in `config-example.toml`. + +#### ircServer + +The address for the IRC server to connect to. + +#### ircNick + +The nick the bot should use. + +#### enableSasl + +Whether to use SASL for authentication. + +#### ircSaslUser + +The SASL username. + +#### ircSaslPass + +The SASL password for SASL plain authentication. + +#### ollamaEndpoint + +The address for the Ollama chat endpoint. + +#### model + +The name of the model to use. + +#### chromaStyle + +The style to use for syntax highlighting done by [chroma](https://github.com/alecthomas/chroma). This is basically what's called a "theme". + +#### chromaFormatter + +The formatter to use. This tells chroma how to generate the color in the output. The supported options are: + +- `noop` for no syntax highlighting +- `terminal` for 8-color terminals +- `terminal8` for 8-color terminals +- `terminal16` for 16-color terminals +- `terminal256` for 256-color terminals +- `terminal16m` for treucolor terminals +- `html` for HTML output + +#### provider + +Which LLM provider to use. The supported options are: + +- [ollama](https://github.com/ollama/ollama) +- chatgpt +- gemini + +#### apikey + +The apikey to use for the LLM provider. + +#### ollamaSystem + +The system message to use for ollama. + +#### clientCertPath + +The path to the client certificate to use for SASL external authentication. + +#### serverPass + +The password to use for the IRC server the bot is trying to connect to if the server has a password. + +#### bind + +Which address to bind to for the IRC server. + +#### temp + +The temperature to config the model with. + +#### requestTimeout + +The timeout for requests made to the LLM provider. + +#### millaReconnectDelay + +How much to wait before reconnecting to the IRC server. + +#### ircPort + +Which port to connect to for the IRC server. + +#### keepAlive + +#### memoryLimit + +How many conversations to keep in memory for a model. + +#### pingDelay + +Ping delay for the IRC server. + +#### pingTimeout + +Ping timeout for the IRC server. + +#### topP + +#### topK + +#### skipTLSVerify + +Skip verifying the IRC server's TLS certificate. This only makes sense if you are trying to connect to an IRC server with a self-signed certificate. + +#### useTLS + +Whether to use TLS to connect to the IRC server. This option is provided to support usage on overlay networks such as Tor, i2p and [yggdrassil](https://github.com/yggdrasil-network/yggdrasil-go). + +#### disableSTSFallback + +#### allowFlood + +Disable [girc](https://github.com/lrstanley/girc)'s built-in flood protection. + +#### debug + +Whether to enable debug logging. The logs are written to stdout. + +#### out + +Whether to write raw messages to stdout. + +#### admins + +List of adimns for the bot. Only admins can use commands. + +``` +admins = ["admin1", "admin2"] ``` -### Deploy +#### ircChannels + +List of channels for the bot to join when it connects to the server. + +``` +ircChannels = ["#channel1", "#channel2"] +``` + +## Commands + +#### help + +Prints the help message. + +#### get -You can use the provided compose file:<br/> +Get the value of a config option. Use the same name as the config file but capitalized. + +#### getall + +Get the value of all config options. + +#### set + +Set a config option on the fly. Use the same name as the config file but capitalized. + +## Deploy + +An example docker compose file is provided in the repo under `docker-compose.yaml`. ```yaml -version: "3.9" services: milla: image: milla @@ -50,6 +197,7 @@ services: resources: limits: memory: 64M + user: ${UID}:${GID} logging: driver: "json-file" options: @@ -60,13 +208,21 @@ services: command: ["--config", "/opt/milla/config.toml"] volumes: - ./config.toml:/opt/milla/config.toml + - /etc/ssl/certs:/etc/ssl/certs:ro cap_drop: - ALL - dns: - - 9.9.9.9 environment: - SERVER_DEPLOYMENT_TYPE=deployment - entrypoint: ["/milla/milla"] networks: millanet: ``` + +## Thanks + +- [girc](https://github.com/lrstanley/girc) +- [chroma](https://github.com/alecthomas/chroma) +- [ollama](https://github.com/ollama/ollama) + +## Similar Projects + +- [soulshack](https://github.com/pkdindustries/soulshack) diff --git a/config-example.toml b/config-example.toml new file mode 100644 index 0000000..9a5a56e --- /dev/null +++ b/config-example.toml @@ -0,0 +1,33 @@ +ircServer = "irc.libera.caht" +ircNick = "milla" +ircSaslUser = "" +ircSaslPass = "" +ollamaEndpoint = "http://127.0.0.1:11434/api/chat" +model = "ollama2-uncensored" +chromaStyle = "monokai" +chromaFormatter = "terminal16m" +provider = "ollama" +apikey = "xxx" +ollamaSystem = "" +clientCertPath = "" +serverPass = "" +bind = "" +temp = 0.5 +requestTimeout = 10 +millaReconnectDelay = 60 +ircPort = 6669 +keepAlive = 20 +memoryLimit = 20 +pingDelay = 20 +pingTimeout = 600 +topP = 0.9 +topK = 0 +enableSasl = false +skipTLSVerify = false +useTLS = true +disableSTSFallback = true +allowFlood = false +debug = false +out = false +admins = ["nick1", "nick2"] +ircChannels = ["##milla1", "##milla2"] diff --git a/docker-compose.yaml b/docker-compose.yaml index 69d0ba5..6e64496 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,4 +1,3 @@ -version: "3.9" services: milla: image: milla @@ -8,6 +7,7 @@ services: resources: limits: memory: 64M + user: ${UID}:${GID} logging: driver: "json-file" options: @@ -15,14 +15,11 @@ services: networks: - millanet restart: unless-stopped - restart: no command: ["--config", "/opt/milla/config.toml"] volumes: - ./config.toml:/opt/milla/config.toml - /etc/ssl/certs:/etc/ssl/certs:ro cap_drop: - ALL - environment: - - SERVER_DEPLOYMENT_TYPE=deployment networks: millanet: @@ -13,7 +13,6 @@ import ( "net/url" "os" "reflect" - "regexp" "strconv" "strings" "time" @@ -138,26 +137,26 @@ func returnGeminiResponse(resp *genai.GenerateContentResponse) string { return result } -func extractLast256ColorEscapeCode(str string) (string, error) { - pattern256F := `\033\[38;5;(\d+)m` - // pattern256B := `\033\[48;5;(\d+)m` - // pattern16mF := `\033\[38;2;(\d+);(\d+);(\d+)m` - // pattern16mB := `\033\[48;2;(\d+);(\d+);(\d+)m` +// func extractLast256ColorEscapeCode(str string) (string, error) { +// pattern256F := `\033\[38;5;(\d+)m` +// // pattern256B := `\033\[48;5;(\d+)m` +// // pattern16mF := `\033\[38;2;(\d+);(\d+);(\d+)m` +// // pattern16mB := `\033\[48;2;(\d+);(\d+);(\d+)m` - r, err := regexp.Compile(pattern256F) - if err != nil { - return "", fmt.Errorf("failed to compile regular expression: %w", err) - } +// r, err := regexp.Compile(pattern256F) +// if err != nil { +// return "", fmt.Errorf("failed to compile regular expression: %w", err) +// } - matches := r.FindAllStringSubmatch(str, -1) - if len(matches) == 0 { - return "", nil - } +// matches := r.FindAllStringSubmatch(str, -1) +// if len(matches) == 0 { +// return "", nil +// } - lastMatch := matches[len(matches)-1] +// lastMatch := matches[len(matches)-1] - return lastMatch[1], nil -} +// return lastMatch[1], nil +// } func chunker(inputString string, chromaFormatter string) []string { chunks := strings.Split(inputString, "\n") @@ -677,9 +676,9 @@ func runIRC(appConfig TomlConfig, ircChan chan *girc.Client) { } } - if appConfig.EnableSasl && appConfig.ClientCertPath != "" { - // TODO - add client cert support - } + // if appConfig.EnableSasl && appConfig.ClientCertPath != "" { + // // TODO - add client cert support + // } irc.Handlers.AddBg(girc.CONNECTED, func(c *girc.Client, e girc.Event) { for _, channel := range appConfig.IrcChannels { |