This commit is contained in:
lyx0 2024-03-05 18:35:46 +01:00
parent b9f14f88a9
commit 6f81209e91
3 changed files with 35 additions and 76 deletions

View file

@ -20,15 +20,6 @@ func (app *application) handleCommand(message twitch.PrivateMessage) {
// e.g. `()ping` would be `ping`. // e.g. `()ping` would be `ping`.
commandName := strings.ToLower(strings.SplitN(message.Message, " ", 3)[0][2:]) 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. // msgLen is the amount of words in a message without the prefix.
// Useful to check if enough cmdParams are provided. // Useful to check if enough cmdParams are provided.
msgLen := len(strings.SplitN(message.Message, " ", -2)) msgLen := len(strings.SplitN(message.Message, " ", -2))
@ -41,7 +32,6 @@ func (app *application) handleCommand(message twitch.PrivateMessage) {
"message.Message", message.Message, "message.Message", message.Message,
"message.Channel", target, "message.Channel", target,
"commandName", commandName, "commandName", commandName,
"cmdParams", cmdParams,
"msgLen", msgLen, "msgLen", msgLen,
) )
@ -53,24 +43,18 @@ func (app *application) handleCommand(message twitch.PrivateMessage) {
// If there is return the data.CommandModel.Text entry. // If there is return the data.CommandModel.Text entry.
// Otherwise we ignore the message. // Otherwise we ignore the message.
switch commandName { switch commandName {
case "":
if msgLen == 1 {
reply = "xd"
}
// --------------------------------
// pleb commands
// --------------------------------
case "gpt": case "gpt":
if msgLen < 2 { if msgLen < 2 {
reply = "Not enough arguments provided. Usage: ()bttv <emote name>" reply = "Not enough arguments provided. Usage: ()gpt <query>"
} else { } 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 != "" { if reply != "" {
go app.Send(target, reply) go app.Send(target, reply)
return return
} }
} }
} }

View file

@ -8,11 +8,11 @@ import (
) )
type ollamaResponse struct { type ollamaResponse struct {
Model string `json:"model"` Model string `json:"model"`
//CreatedAt string `json:"created_at"` CreatedAt string `json:"created_at"`
Response string `json:"response"` Response string `json:"response"`
Done bool `json:"done"` Done bool `json:"done"`
Message ollamaMessage `json:"message"` Message ollamaMessage `json:"message"`
} }
type ollamaRequest struct { type ollamaRequest struct {
@ -30,29 +30,20 @@ type ollamaMessage struct {
Content string `json:"content"` Content string `json:"content"`
} }
func startMessage() []ollamaMessage { var requestBody ollamaRequest
var msg = make([]ollamaMessage, 0)
return msg
}
//func initStore() *map[string][]ollamaMessage { // chatUserContext provides additional message context from specifically
// personalMsgStore := make(map[string][]ollamaMessage) // the past interactions of user with the AI since last restart.
// return &personalMsgStore func (app *application) chatUserContext(target, username, input string) {
//}
func (app *application) chatPersonalContext(target, username, input string) {
var requestBody ollamaRequest
//var msg []ollamaMessage
olm := ollamaMessage{} olm := ollamaMessage{}
olm.Role = "user" olm.Role = "user"
olm.Content = input olm.Content = input
app.PersonalMsgStore[username] = append(app.PersonalMsgStore[username], olm) app.UserMsgStore[username] = append(app.UserMsgStore[username], olm)
//msgStore = append(msgStore, olm)
requestBody.Model = "wizard-vicuna-uncensored" 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.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.Prompt = input
requestBody.Stream = false requestBody.Stream = false
@ -77,25 +68,21 @@ func (app *application) chatPersonalContext(target, username, input string) {
if err := json.Unmarshal(body, &responseObject); err != nil { if err := json.Unmarshal(body, &responseObject); err != nil {
app.Log.Error(err) app.Log.Error(err)
} }
olm.Role = responseObject.Message.Role olm.Role = responseObject.Message.Role
olm.Content = responseObject.Message.Content 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", app.Log.Infow("Message context for username",
"Username", 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.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) { func (app *application) chatGeneralContext(target, input string) {
var requestBody ollamaRequest
//var msg []ollamaMessage
olm := ollamaMessage{} olm := ollamaMessage{}
olm.Role = "user" olm.Role = "user"
@ -113,9 +100,6 @@ func (app *application) chatGeneralContext(target, input string) {
app.Log.Error(err) 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)) resp, err := http.Post("http://localhost:11434/api/chat", "application/json", bytes.NewBuffer(marshalled))
if err != nil { if err != nil {
app.Log.Error(err.Error()) app.Log.Error(err.Error())
@ -132,6 +116,7 @@ func (app *application) chatGeneralContext(target, input string) {
if err := json.Unmarshal(body, &responseObject); err != nil { if err := json.Unmarshal(body, &responseObject); err != nil {
app.Log.Error(err) app.Log.Error(err)
} }
olm.Role = responseObject.Message.Role olm.Role = responseObject.Message.Role
olm.Content = responseObject.Message.Content olm.Content = responseObject.Message.Content
app.MsgStore = append(app.MsgStore, olm) app.MsgStore = append(app.MsgStore, olm)
@ -140,18 +125,14 @@ func (app *application) chatGeneralContext(target, input string) {
"app.MsgStore", app.MsgStore, "app.MsgStore", app.MsgStore,
) )
app.Send(target, responseObject.Message.Content) app.Send(target, responseObject.Message.Content)
//app.Send(target, responseObject.Response)
} }
// generateNoContext provides no additional message context
func (app *application) generateNoContext(target, input string) { func (app *application) generateNoContext(target, input string) {
var requestBody ollamaRequest var requestBody ollamaRequest
requestBody.Model = "wizard-vicuna-uncensored" 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.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.Prompt = input
requestBody.Stream = false requestBody.Stream = false
@ -176,7 +157,6 @@ func (app *application) generateNoContext(target, input string) {
if err := json.Unmarshal(body, &responseObject); err != nil { if err := json.Unmarshal(body, &responseObject); err != nil {
app.Log.Error(err) app.Log.Error(err)
} }
//app.Log.Info(responseObject.Message.Content)
//app.Send(target, responseObject.Message.Content)
app.Send(target, responseObject.Response) app.Send(target, responseObject.Response)
} }

View file

@ -19,12 +19,12 @@ type config struct {
} }
type application struct { type application struct {
TwitchClient *twitch.Client TwitchClient *twitch.Client
Log *zap.SugaredLogger Log *zap.SugaredLogger
Environment string Environment string
Config config Config config
PersonalMsgStore map[string][]ollamaMessage UserMsgStore map[string][]ollamaMessage
MsgStore []ollamaMessage MsgStore []ollamaMessage
} }
func main() { func main() {
@ -60,12 +60,12 @@ func run(ctx context.Context, w io.Writer, args []string) error {
cfg.twitchOauth = os.Getenv("TWITCH_OAUTH") cfg.twitchOauth = os.Getenv("TWITCH_OAUTH")
tc := twitch.NewClient(cfg.twitchUsername, cfg.twitchOauth) tc := twitch.NewClient(cfg.twitchUsername, cfg.twitchOauth)
personalMsgStore := make(map[string][]ollamaMessage) userMsgStore := make(map[string][]ollamaMessage)
app := &application{ app := &application{
TwitchClient: tc, TwitchClient: tc,
Log: sugar, Log: sugar,
Config: cfg, Config: cfg,
PersonalMsgStore: personalMsgStore, UserMsgStore: userMsgStore,
} }
// Received a PrivateMessage (normal chat message). // 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. // Message was shorter than our prefix is therefore it's irrelevant for us.
if len(message.Message) >= 2 { 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. // Check if the first 2 characters of the mesage were our prefix.
// if they were forward the message to the command handler. // if they were forward the message to the command handler.
if message.Message[:2] == "()" { if message.Message[:2] == "()" {
go app.handleCommand(message) go app.handleCommand(message)
return 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("nouryxd")
app.TwitchClient.Join("nourybot")
// Actually connect to chat. // Actually connect to chat.
err = app.TwitchClient.Connect() err = app.TwitchClient.Connect()