From 118693d4e44a1d737b336918eb1d385e01f292a0 Mon Sep 17 00:00:00 2001 From: Alexey Skobkin Date: Tue, 12 Mar 2024 05:14:23 +0300 Subject: [PATCH 1/3] Trying to send error about failed reply. --- bot/bot.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/bot/bot.go b/bot/bot.go index ef8b03f..0c6c391 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -114,6 +114,8 @@ func (b *Bot) heyHandler(bot *telego.Bot, update telego.Update) { if err != nil { slog.Error("Can't send reply message", err) + + b.trySendReplyError(update.Message) } } @@ -179,6 +181,8 @@ func (b *Bot) summarizeHandler(bot *telego.Bot, update telego.Update) { if err != nil { slog.Error("Can't send reply message", err) + + b.trySendReplyError(update.Message) } } @@ -198,6 +202,8 @@ func (b *Bot) helpHandler(bot *telego.Bot, update telego.Update) { ))) if err != nil { slog.Error("Cannot send a message", err) + + b.trySendReplyError(update.Message) } } @@ -215,6 +221,8 @@ func (b *Bot) startHandler(bot *telego.Bot, update telego.Update) { ))) if err != nil { slog.Error("Cannot send a message", err) + + b.trySendReplyError(update.Message) } } @@ -234,6 +242,8 @@ func (b *Bot) statsHandler(bot *telego.Bot, update telego.Update) { )).WithParseMode("Markdown")) if err != nil { slog.Error("Cannot send a message", err) + + b.trySendReplyError(update.Message) } } @@ -251,3 +261,14 @@ func (b *Bot) sendTyping(chatId telego.ChatID) { slog.Error("Cannot set chat action", err) } } + +func (b *Bot) trySendReplyError(message *telego.Message) { + if message == nil { + return + } + + _, _ = b.api.SendMessage(b.reply(message, tu.Message( + tu.ID(message.Chat.ID), + "Error occurred while trying to send reply.", + ))) +} From 1343d0c4f8f908e9709816472976b1acefffd7cb Mon Sep 17 00:00:00 2001 From: Alexey Skobkin Date: Tue, 12 Mar 2024 05:14:50 +0300 Subject: [PATCH 2/3] Logging 'typing' notification only in Debug level. --- bot/bot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/bot.go b/bot/bot.go index 0c6c391..cd6c483 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -254,7 +254,7 @@ func (b *Bot) reply(originalMessage *telego.Message, newMessage *telego.SendMess } func (b *Bot) sendTyping(chatId telego.ChatID) { - slog.Info("Setting 'typing' chat action") + slog.Debug("Setting 'typing' chat action") err := b.api.SendChatAction(tu.ChatAction(chatId, "typing")) if err != nil { From dc5ad2c580aa98ea872679510f316309c336a00f Mon Sep 17 00:00:00 2001 From: Alexey Skobkin Date: Tue, 12 Mar 2024 06:12:25 +0300 Subject: [PATCH 3/3] Implementing request context and adding it to /hey command processing. --- bot/bot.go | 39 ++++++++++++++++++++++++++++++++++++++- llm/llm.go | 9 ++++++--- llm/request_context.go | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 llm/request_context.go diff --git a/bot/bot.go b/bot/bot.go index cd6c483..e855eb2 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -87,11 +87,19 @@ func (b *Bot) heyHandler(bot *telego.Bot, update telego.Update) { b.stats.HeyRequest() + parts := strings.SplitN(update.Message.Text, " ", 2) + userMessage := "Hey!" + if len(parts) == 2 { + userMessage = parts[1] + } + chatID := tu.ID(update.Message.Chat.ID) b.sendTyping(chatID) - llmReply, err := b.llm.HandleSingleRequest(update.Message.Text, llm.ModelMistralUncensored) + requestContext := b.createLlmRequestContext(update) + + llmReply, err := b.llm.HandleSingleRequest(userMessage, llm.ModelMistralUncensored, requestContext) if err != nil { slog.Error("Cannot get reply from LLM connector") @@ -247,6 +255,35 @@ func (b *Bot) statsHandler(bot *telego.Bot, update telego.Update) { } } +func (b *Bot) createLlmRequestContext(update telego.Update) llm.RequestContext { + message := update.Message + + rc := llm.RequestContext{} + + if message == nil { + return rc + } + + user := message.From + if user != nil { + rc.User = llm.UserContext{ + Username: user.Username, + FirstName: user.FirstName, + LastName: user.LastName, + IsPremium: user.IsPremium, + } + } + + chat := message.Chat + rc.Chat = llm.ChatContext{ + Title: chat.Title, + Description: chat.Description, + Type: chat.Type, + } + + return rc +} + func (b *Bot) reply(originalMessage *telego.Message, newMessage *telego.SendMessageParams) *telego.SendMessageParams { return newMessage.WithReplyParameters(&telego.ReplyParameters{ MessageID: originalMessage.MessageID, diff --git a/llm/llm.go b/llm/llm.go index 483a36e..4a5084b 100644 --- a/llm/llm.go +++ b/llm/llm.go @@ -29,13 +29,16 @@ func NewConnector(baseUrl string, token string) *LlmConnector { } } -func (l *LlmConnector) HandleSingleRequest(text string, model string) (string, error) { +func (l *LlmConnector) HandleSingleRequest(text string, model string, requestContext RequestContext) (string, error) { req := openai.ChatCompletionRequest{ Model: model, Messages: []openai.ChatCompletionMessage{ { - Role: openai.ChatMessageRoleSystem, - Content: "You're a bot in the Telegram chat. You are replying to questions directed to you.", + Role: openai.ChatMessageRoleSystem, + Content: "You're a bot in the Telegram chat. " + + "You're using a free model called \"" + model + "\". " + + "You see only messages addressed to you using commands due to privacy settings. " + + requestContext.Prompt(), }, }, } diff --git a/llm/request_context.go b/llm/request_context.go new file mode 100644 index 0000000..4ba248b --- /dev/null +++ b/llm/request_context.go @@ -0,0 +1,38 @@ +package llm + +type RequestContext struct { + User UserContext + Chat ChatContext +} + +type UserContext struct { + Username string + FirstName string + LastName string + IsPremium bool +} + +type ChatContext struct { + Title string + Description string + Type string +} + +func (c RequestContext) Prompt() string { + prompt := "The chat you're in is called \"" + c.Chat.Title + "\". " + + "The type of chat is \"" + c.Chat.Type + "\". " + + "The chat description is \"" + c.Chat.Description + "\". " + if c.User.Username != "" { + prompt += "The user who wrote you has username \"@" + c.Chat.Description + "\". " + } + prompt += "Their first name is \"" + c.User.FirstName + "\". " + if c.User.LastName != "" { + prompt += "Their last name is \"" + c.User.LastName + "\". " + } + + if c.User.IsPremium { + prompt += "They have Telegram Premium subscription. " + } + + return prompt +}