diff options
Diffstat (limited to 'bot.go')
-rw-r--r-- | bot.go | 62 |
1 files changed, 32 insertions, 30 deletions
@@ -23,41 +23,32 @@ var httpClient = http.Client{ var ( logger *slog.Logger - APIURL = "http://localhost:8080/v1/chat/completions" - DB = map[string]map[string]any{} userRole = "user" assistantRole = "assistant" toolRole = "tool" assistantIcon = "<🤖>: " userIcon = "<user>: " - historyDir = "./history/" - // TODO: pass as an cli arg + // TODO: pass as an cli arg or have config + APIURL = "http://localhost:8080/v1/chat/completions" + logFileName = "log.txt" showSystemMsgs bool + chunkLimit = 1000 activeChatName string chunkChan = make(chan string, 10) streamDone = make(chan bool, 1) chatBody *models.ChatBody - store storage.ChatHistory + store storage.FullRepo defaultFirstMsg = "Hello! What can I do for you?" defaultStarter = []models.MessagesStory{ {Role: "system", Content: systemMsg}, {Role: assistantRole, Content: defaultFirstMsg}, } - interruptResp = false + defaultStarterBytes = []byte{} + interruptResp = false ) // ==== -func getUserInput(userPrompt string) string { - fmt.Printf(userPrompt) - reader := bufio.NewReader(os.Stdin) - line, err := reader.ReadString('\n') - if err != nil { - panic(err) // think about it - } - return line -} - func formMsg(chatBody *models.ChatBody, newMsg, role string) io.Reader { if newMsg != "" { // otherwise let the bot continue newMsg := models.MessagesStory{Role: role, Content: newMsg} @@ -65,7 +56,8 @@ func formMsg(chatBody *models.ChatBody, newMsg, role string) io.Reader { } data, err := json.Marshal(chatBody) if err != nil { - panic(err) + logger.Error("failed to form a msg", "error", err) + return nil } return bytes.NewReader(data) } @@ -89,14 +81,15 @@ func sendMsgToLLM(body io.Reader) (any, error) { break } llmchunk := models.LLMRespChunk{} - if counter > 2000 { + if counter > chunkLimit { + logger.Warn("response hit chunk limit", "limit", chunkLimit) streamDone <- true break } line, err := reader.ReadBytes('\n') if err != nil { streamDone <- true - panic(err) + logger.Error("error reading response body", "error", err) } // logger.Info("linecheck", "line", string(line), "len", len(line), "counter", counter) if len(line) <= 1 { @@ -128,6 +121,9 @@ func sendMsgToLLM(body io.Reader) (any, error) { func chatRound(userMsg, role string, tv *tview.TextView) { botRespMode = true reader := formMsg(chatBody, userMsg, role) + if reader == nil { + return // any notification in that case? + } go sendMsgToLLM(reader) fmt.Fprintf(tv, fmt.Sprintf("(%d) ", len(chatBody.Messages))) fmt.Fprintf(tv, assistantIcon) @@ -159,18 +155,22 @@ out: } func findCall(msg string, tv *tview.TextView) { - prefix := "__tool_call__\n" - suffix := "\n__tool_call__" + // prefix := "__tool_call__\n" + // suffix := "\n__tool_call__" + // if !strings.HasPrefix(msg, prefix) || + // !strings.HasSuffix(msg, suffix) { + // return + // } + // jsStr := strings.TrimSuffix(strings.TrimPrefix(msg, prefix), suffix) fc := models.FuncCall{} - if !strings.HasPrefix(msg, prefix) || - !strings.HasSuffix(msg, suffix) { + jsStr := toolCallRE.FindString(msg) + if jsStr == "" { + // tool call not found return } - jsStr := strings.TrimSuffix(strings.TrimPrefix(msg, prefix), suffix) if err := json.Unmarshal([]byte(jsStr), &fc); err != nil { logger.Error("failed to unmarshal tool call", "error", err) return - // panic(err) } // call a func f, ok := fnMap[fc.Name] @@ -229,13 +229,15 @@ func textSliceToChat(chat []string) []models.MessagesStory { } func init() { - file, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + file, err := os.OpenFile(logFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { - panic(err) + logger.Error("failed to open log file", "error", err, "filename", logFileName) + return } - // create dir if does not exist - if err := os.MkdirAll(historyDir, os.ModePerm); err != nil { - panic(err) + defaultStarterBytes, err = json.Marshal(defaultStarter) + if err != nil { + logger.Error("failed to marshal defaultStarter", "error", err) + return } logger = slog.New(slog.NewTextHandler(file, nil)) store = storage.NewProviderSQL("test.db", logger) |