diff options
Diffstat (limited to 'openrouter.go')
-rw-r--r-- | openrouter.go | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/openrouter.go b/openrouter.go new file mode 100644 index 0000000..8a1a1e5 --- /dev/null +++ b/openrouter.go @@ -0,0 +1,200 @@ +package main + +import ( + "bytes" + "context" + "encoding/json" + "log" + "net" + "net/http" + "net/url" + "strings" + "time" + + "github.com/alecthomas/chroma/v2/quick" + "github.com/lrstanley/girc" + "golang.org/x/net/proxy" +) + +func DoORRequest( + appConfig *TomlConfig, + memory *[]MemoryElement, + prompt string, +) (string, error) { + var jsonPayload []byte + + var err error + + memoryElement := MemoryElement{ + Role: "user", + Content: prompt, + } + + if len(*memory) > appConfig.MemoryLimit { + *memory = []MemoryElement{} + + for _, context := range appConfig.Context { + *memory = append(*memory, MemoryElement{ + Role: "assistant", + Content: context, + }) + } + } + + *memory = append(*memory, memoryElement) + + ollamaRequest := OllamaChatRequest{ + Model: appConfig.Model, + Messages: *memory, + } + + jsonPayload, err = json.Marshal(ollamaRequest) + if err != nil { + + return "", err + } + + log.Printf("json payload: %s", string(jsonPayload)) + + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(appConfig.RequestTimeout)*time.Second) + defer cancel() + + request, err := http.NewRequest(http.MethodPost, appConfig.Endpoint, bytes.NewBuffer(jsonPayload)) + if err != nil { + + return "", err + } + + request = request.WithContext(ctx) + request.Header.Set("content-type", "application/json") + request.Header.Set("Authorization", "Bearer "+appConfig.Apikey) + + var httpClient http.Client + + var dialer proxy.Dialer + + if appConfig.LLMProxy != "" { + proxyURL, err := url.Parse(appConfig.IRCProxy) + if err != nil { + cancel() + + log.Fatal(err.Error()) + } + + dialer, err = proxy.FromURL(proxyURL, &net.Dialer{Timeout: time.Duration(appConfig.RequestTimeout) * time.Second}) + if err != nil { + cancel() + + log.Fatal(err.Error()) + } + + httpClient = http.Client{ + Transport: &http.Transport{ + Dial: dialer.Dial, + }, + } + } + response, err := httpClient.Do(request) + + if err != nil { + return "", err + } + + defer response.Body.Close() + + log.Println("response body:", response.Body) + + var orresponse ORResponse + + err = json.NewDecoder(response.Body).Decode(&orresponse) + if err != nil { + return "", err + } + + var result string + + for _, choice := range orresponse.Choices { + result += choice.Message.Content + "\n" + } + + return result, nil +} + +func ORRequestProcessor( + appConfig *TomlConfig, + client *girc.Client, + event girc.Event, + memory *[]MemoryElement, + prompt string, +) string { + response, err := DoORRequest(appConfig, memory, prompt) + if err != nil { + client.Cmd.ReplyTo(event, "error: "+err.Error()) + + return "" + } + + assistantElement := MemoryElement{ + Role: "assistant", + Content: response, + } + + *memory = append(*memory, assistantElement) + + log.Println(response) + + var writer bytes.Buffer + + err = quick.Highlight(&writer, + response, + "markdown", + appConfig.ChromaFormatter, + appConfig.ChromaStyle) + if err != nil { + client.Cmd.ReplyTo(event, "error: "+err.Error()) + + return "" + } + + return writer.String() +} + +func ORHandler( + irc *girc.Client, + appConfig *TomlConfig, + memory *[]MemoryElement) { + irc.Handlers.AddBg(girc.PRIVMSG, func(client *girc.Client, event girc.Event) { + if !strings.HasPrefix(event.Last(), appConfig.IrcNick+": ") { + return + } + + if appConfig.AdminOnly { + byAdmin := false + + for _, admin := range appConfig.Admins { + if event.Source.Name == admin { + byAdmin = true + } + } + + if !byAdmin { + return + } + } + + prompt := strings.TrimPrefix(event.Last(), appConfig.IrcNick+": ") + log.Println(prompt) + + if string(prompt[0]) == "/" { + runCommand(client, event, appConfig) + + return + } + + result := ORRequestProcessor(appConfig, client, event, memory, prompt) + if result != "" { + sendToIRC(client, event, result, appConfig.ChromaFormatter) + } + }) + +} |