From 2a8605631be7a723a4ae774fbdc95fb1a1614092 Mon Sep 17 00:00:00 2001 From: Yiyang Kang Date: Fri, 21 Apr 2023 15:43:05 +0800 Subject: [PATCH] feat: add kanji command --- assistant.go | 2 + bot.go | 1 + botcmd_kanji.go | 77 +++++++++++++++++++++++++++++++++++++++ main.go | 1 + openai/prompts/prompts.go | 15 ++++++++ 5 files changed, 96 insertions(+) create mode 100644 botcmd_kanji.go diff --git a/assistant.go b/assistant.go index 4b4ef18..6b0cce5 100644 --- a/assistant.go +++ b/assistant.go @@ -91,6 +91,8 @@ func matchAssistantConversation(botUsr *tele.User, msg *tele.Message) []*tele.Me type assistantStreamedResponseCb func(text string, finished bool) error +// TODO interrupt response with context. + func assistantStreamedResponse(request openai.ChatRequest, cb assistantStreamedResponseCb) error { logger.Debugw("Openai chat request", "req", request) ai := openai.NewClient(config.OpenAIApiKey) diff --git a/bot.go b/bot.go index d805bc9..b59b099 100644 --- a/bot.go +++ b/bot.go @@ -42,6 +42,7 @@ func initBot() (*tele.Bot, error) { for _, tbtn := range translateBtns { b.Handle(tbtn, handleTranslateBtn) } + b.Handle("/kanji", handleKanjiCmd) b.Handle(tele.OnText, handleGeneralMessage) b.Handle(tele.OnSticker, handleGeneralMessage) diff --git a/botcmd_kanji.go b/botcmd_kanji.go new file mode 100644 index 0000000..10e15cf --- /dev/null +++ b/botcmd_kanji.go @@ -0,0 +1,77 @@ +package main + +import ( + "regexp" + "strings" + + "github.com/samber/lo" + tele "gopkg.in/telebot.v3" + + "git.gensokyo.cafe/kkyy/tgbot_misaka_5882f7/openai" + "git.gensokyo.cafe/kkyy/tgbot_misaka_5882f7/openai/prompts" +) + +var kanjiRe = regexp.MustCompile(`\p{Han}`) + +func handleKanjiCmd(c tele.Context) error { + msg := c.Message() + if msg == nil { + return nil + } + + payload := strings.TrimSpace(msg.Payload) + if payload == "" { + return c.Reply("Usage: `/kanji `", &tele.SendOptions{ParseMode: tele.ModeMarkdown}, tele.Silent) + } + if !kanjiRe.MatchString(payload) { + return c.Reply("// Your text does not contain any Kanji.") + } + + req := openai.ChatRequest{ + Model: openai.ModelGpt0305Turbo, + Messages: []openai.ChatMessage{ + { + Role: openai.ChatRoleSystem, + Content: prompts.KanjiPronunciation(), + }, + { + Role: openai.ChatRoleUser, + Content: payload, + }, + { + Role: openai.ChatRoleSystem, + Content: `Reminder: Assistant should stick to the task of adding pronunciations for Kanji in the text sent by the user. If user's message seem irrelevant, just reply "IRRELEVANT"`, + }, + }, + Temperature: lo.ToPtr(0.2), + } + + actionCh := setTyping(c) + var irrelevant = false + var replyMsg *tele.Message + err := assistantStreamedResponse(req, func(text string, finished bool) error { + <-actionCh + if strings.HasPrefix(text, `IRRELEVANT`) { + irrelevant = true + return nil // TODO interrupt response + } + var err error + if replyMsg == nil { + replyMsg, err = c.Bot().Reply(msg, text, tele.Silent) + } else { + replyMsg, err = c.Bot().Edit(replyMsg, text) + } + return err + }) + + if err != nil { + logger.Errorw("assistant: failed to complete conversation", "error", err) + _ = c.Reply("Sorry, there's a technical issue. ๐Ÿ˜ต๐Ÿ’ซ Please try again later.", tele.Silent) + return err + } + + if irrelevant { + return c.Reply("Sorry, I don't know what to do with your input.") + } + return nil +} diff --git a/main.go b/main.go index 2872bbb..b009728 100644 --- a/main.go +++ b/main.go @@ -42,6 +42,7 @@ func runBot() { if err = bot.SetCommands([]tele.Command{ {Text: "tr", Description: "Translate text"}, + {Text: "kanji", Description: "Help with pronunciation of Kanji"}, {Text: "xr", Description: "Currency exchange rates"}, {Text: "year_progress", Description: "Time doesn't wait."}, {Text: "traffic", Description: "Show traffic usage."}, diff --git a/openai/prompts/prompts.go b/openai/prompts/prompts.go index dbd9a73..03aa02b 100644 --- a/openai/prompts/prompts.go +++ b/openai/prompts/prompts.go @@ -31,3 +31,18 @@ func Translate(targetLang string) string { targetLang, ) } + +func KanjiPronunciation() string { + return strings.Join([]string{ + `You are a helpful assistant. Your task is to help with pronunciation of Kanji in Japanese.`, + ``, + `The user must send text in Japanese, otherwise it would be irrelevant to your task, and you must ignore them.`, + ``, + `You must then reply with the exact same text as sent by the user, with pronunciations (hiragana) added for every occurrence of Kanji in the text.`, + ``, + `Example`, + ``, + `User: ่—คๅŽŸๆ›ธ่จ˜ใฏใ€ๆผซ็”ปใ€Žใ‹ใใ‚„ๆง˜ใฏๅ‘Šใ‚‰ใ›ใŸใ„๏ฝžๅคฉๆ‰ใŸใกใฎๆ‹ๆ„›้ ญ่„ณๆˆฆ๏ฝžใ€ใซ`, + `Assistant: ่—คๅŽŸ(ใตใ˜ใ‚ใ‚‰)ๆ›ธ่จ˜(ใ—ใ‚‡ใ)ใฏใ€ๆผซ็”ป(ใพใ‚“ใŒ)ใ€Žใ‹ใใ‚„ๆง˜(ใ•ใพ)ใฏๅ‘Š(ใ“ใ)ใ‚‰ใ›ใŸใ„๏ฝžๅคฉๆ‰(ใฆใ‚“ใ•ใ„)ใŸใกใฎๆ‹ๆ„›(ใ‚Œใ‚“ใ‚ใ„)้ ญ่„ณๆˆฆ(ใšใฎใ†ใ›ใ‚“)๏ฝžใ€ใซ`, + }, "\n") +}