aboutsummaryrefslogtreecommitdiffstats
path: root/openrouter.go
diff options
context:
space:
mode:
authorterminaldweller <devi@terminaldweller.com>2024-10-28 22:28:16 +0000
committerterminaldweller <devi@terminaldweller.com>2024-10-28 22:28:16 +0000
commite22d58cee6d9bb963f879fde8890e7743269afb3 (patch)
tree7521268ce29b4fca3b97bfe7451a828b7b880ca5 /openrouter.go
parentadded a new option, context. fixed a bug with the custom commands where the c... (diff)
downloadmilla-e22d58cee6d9bb963f879fde8890e7743269afb3.tar.gz
milla-e22d58cee6d9bb963f879fde8890e7743269afb3.zip
added openrouter as a provider
Diffstat (limited to 'openrouter.go')
-rw-r--r--openrouter.go200
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)
+ }
+ })
+
+}