diff --git a/cmd/nourybot/commands.go b/cmd/nourybot/commands.go index 1e7d741..24bc668 100644 --- a/cmd/nourybot/commands.go +++ b/cmd/nourybot/commands.go @@ -20,15 +20,6 @@ func (app *application) handleCommand(message twitch.PrivateMessage) { // e.g. `()ping` would be `ping`. commandName := strings.ToLower(strings.SplitN(message.Message, " ", 3)[0][2:]) - // cmdParams are additional command parameters. - // e.g. `()weather san antonio` - // cmdParam[0] is `san` and cmdParam[1] = `antonio`. - // - // Since Twitch messages are at most 500 characters I use a - // maximum count of 500+10 just to be safe. - // https://discuss.dev.twitch.tv/t/missing-client-side-message-length-check/21316 - cmdParams := strings.SplitN(message.Message, " ", 500) - // msgLen is the amount of words in a message without the prefix. // Useful to check if enough cmdParams are provided. msgLen := len(strings.SplitN(message.Message, " ", -2)) @@ -41,7 +32,6 @@ func (app *application) handleCommand(message twitch.PrivateMessage) { "message.Message", message.Message, "message.Channel", target, "commandName", commandName, - "cmdParams", cmdParams, "msgLen", msgLen, ) @@ -53,24 +43,18 @@ func (app *application) handleCommand(message twitch.PrivateMessage) { // If there is return the data.CommandModel.Text entry. // Otherwise we ignore the message. switch commandName { - case "": - if msgLen == 1 { - reply = "xd" - } - // -------------------------------- - // pleb commands - // -------------------------------- case "gpt": if msgLen < 2 { - reply = "Not enough arguments provided. Usage: ()bttv " + reply = "Not enough arguments provided. Usage: ()gpt " } else { - app.chatPersonalContext(target, message.User.Name, message.Message[6:len(message.Message)]) + //app.generateNoContext(target, message.User.Name, message.Message[6:len(message.Message)]) + //app.chatGeneralContext(target, message.User.Name, message.Message[6:len(message.Message)]) + app.chatUserContext(target, message.User.Name, message.Message[6:len(message.Message)]) } if reply != "" { go app.Send(target, reply) return } - } } diff --git a/cmd/nourybot/generate.go b/cmd/nourybot/generate.go index 8bf18fe..288815a 100644 --- a/cmd/nourybot/generate.go +++ b/cmd/nourybot/generate.go @@ -8,11 +8,11 @@ import ( ) type ollamaResponse struct { - Model string `json:"model"` - //CreatedAt string `json:"created_at"` - Response string `json:"response"` - Done bool `json:"done"` - Message ollamaMessage `json:"message"` + Model string `json:"model"` + CreatedAt string `json:"created_at"` + Response string `json:"response"` + Done bool `json:"done"` + Message ollamaMessage `json:"message"` } type ollamaRequest struct { @@ -30,29 +30,20 @@ type ollamaMessage struct { Content string `json:"content"` } -func startMessage() []ollamaMessage { - var msg = make([]ollamaMessage, 0) - return msg -} +var requestBody ollamaRequest -//func initStore() *map[string][]ollamaMessage { -// personalMsgStore := make(map[string][]ollamaMessage) -// return &personalMsgStore -//} - -func (app *application) chatPersonalContext(target, username, input string) { - var requestBody ollamaRequest - //var msg []ollamaMessage +// chatUserContext provides additional message context from specifically +// the past interactions of user with the AI since last restart. +func (app *application) chatUserContext(target, username, input string) { olm := ollamaMessage{} olm.Role = "user" olm.Content = input - app.PersonalMsgStore[username] = append(app.PersonalMsgStore[username], olm) - //msgStore = append(msgStore, olm) + app.UserMsgStore[username] = append(app.UserMsgStore[username], olm) requestBody.Model = "wizard-vicuna-uncensored" requestBody.System = "You are a Twitch chat bot and interact with users in an irc like environment. Do not use any formatting. Be human-like. Never fail to answer the user. Always answer immediately. Keep your response shorter than 450 characters." - requestBody.Messages = app.PersonalMsgStore[username] + requestBody.Messages = app.UserMsgStore[username] requestBody.Prompt = input requestBody.Stream = false @@ -77,25 +68,21 @@ func (app *application) chatPersonalContext(target, username, input string) { if err := json.Unmarshal(body, &responseObject); err != nil { app.Log.Error(err) } + olm.Role = responseObject.Message.Role olm.Content = responseObject.Message.Content - app.PersonalMsgStore[username] = append(app.PersonalMsgStore[username], olm) + app.UserMsgStore[username] = append(app.UserMsgStore[username], olm) app.Log.Infow("Message context for username", "Username", username, - "Personal Context", app.PersonalMsgStore[username], + "Personal Context", app.UserMsgStore[username], ) - //app.Log.Infow("Complete message context", - // "Context", app.PersonalMsgStore, - //) - app.Send(target, responseObject.Message.Content) - //app.Send(target, responseObject.Response) } +// chatGeneralContext provides additional message context from every past +// interaction with the AI since last restart. func (app *application) chatGeneralContext(target, input string) { - var requestBody ollamaRequest - //var msg []ollamaMessage olm := ollamaMessage{} olm.Role = "user" @@ -113,9 +100,6 @@ func (app *application) chatGeneralContext(target, input string) { app.Log.Error(err) } - app.Log.Infow("MsgStore", - "app.MsgStore", app.MsgStore, - ) resp, err := http.Post("http://localhost:11434/api/chat", "application/json", bytes.NewBuffer(marshalled)) if err != nil { app.Log.Error(err.Error()) @@ -132,6 +116,7 @@ func (app *application) chatGeneralContext(target, input string) { if err := json.Unmarshal(body, &responseObject); err != nil { app.Log.Error(err) } + olm.Role = responseObject.Message.Role olm.Content = responseObject.Message.Content app.MsgStore = append(app.MsgStore, olm) @@ -140,18 +125,14 @@ func (app *application) chatGeneralContext(target, input string) { "app.MsgStore", app.MsgStore, ) app.Send(target, responseObject.Message.Content) - //app.Send(target, responseObject.Response) } +// generateNoContext provides no additional message context func (app *application) generateNoContext(target, input string) { var requestBody ollamaRequest requestBody.Model = "wizard-vicuna-uncensored" requestBody.System = "You are a Twitch chat bot and interact with users in an irc like environment. Do not use any formatting. Be human-like. Never fail to answer the user. Always answer immediately. Keep your response shorter than 450 characters." - //requestBody.Messages.Role = "system" - //requestBody.Messages.Content = "You are a Twitch chat bot and interact with users in an irc like environment. Do not use any formatting. Be blunt. Never fail to answer the user. Always answer immediately. Keep your response shorter than 450 characters." - //requestBody.Messages.Role = "user" - //requestBody.Messages.Content = input requestBody.Prompt = input requestBody.Stream = false @@ -176,7 +157,6 @@ func (app *application) generateNoContext(target, input string) { if err := json.Unmarshal(body, &responseObject); err != nil { app.Log.Error(err) } - //app.Log.Info(responseObject.Message.Content) - //app.Send(target, responseObject.Message.Content) + app.Send(target, responseObject.Response) } diff --git a/cmd/nourybot/main.go b/cmd/nourybot/main.go index b9d3c7a..bec1452 100644 --- a/cmd/nourybot/main.go +++ b/cmd/nourybot/main.go @@ -19,12 +19,12 @@ type config struct { } type application struct { - TwitchClient *twitch.Client - Log *zap.SugaredLogger - Environment string - Config config - PersonalMsgStore map[string][]ollamaMessage - MsgStore []ollamaMessage + TwitchClient *twitch.Client + Log *zap.SugaredLogger + Environment string + Config config + UserMsgStore map[string][]ollamaMessage + MsgStore []ollamaMessage } func main() { @@ -60,12 +60,12 @@ func run(ctx context.Context, w io.Writer, args []string) error { cfg.twitchOauth = os.Getenv("TWITCH_OAUTH") tc := twitch.NewClient(cfg.twitchUsername, cfg.twitchOauth) - personalMsgStore := make(map[string][]ollamaMessage) + userMsgStore := make(map[string][]ollamaMessage) app := &application{ - TwitchClient: tc, - Log: sugar, - Config: cfg, - PersonalMsgStore: personalMsgStore, + TwitchClient: tc, + Log: sugar, + Config: cfg, + UserMsgStore: userMsgStore, } // Received a PrivateMessage (normal chat message). @@ -79,18 +79,12 @@ func run(ctx context.Context, w io.Writer, args []string) error { // Message was shorter than our prefix is therefore it's irrelevant for us. if len(message.Message) >= 2 { - // This bots prefix is "()" configured above at cfg.commandPrefix, // Check if the first 2 characters of the mesage were our prefix. // if they were forward the message to the command handler. if message.Message[:2] == "()" { go app.handleCommand(message) return } - - // Special rule for #pajlada. - if message.Message == "!nourybot" { - app.Send(message.Channel, "Lidl Twitch bot made by @nouryxd. Prefix: ()") - } } }) @@ -105,6 +99,7 @@ func run(ctx context.Context, w io.Writer, args []string) error { }) app.TwitchClient.Join("nouryxd") + app.TwitchClient.Join("nourybot") // Actually connect to chat. err = app.TwitchClient.Connect()