emdb/worker/main.go

129 lines
3.3 KiB
Go
Raw Normal View History

2023-12-29 19:10:31 +01:00
package main
import (
2023-12-30 13:09:23 +01:00
"context"
2024-01-20 11:02:00 +01:00
"encoding/json"
2023-12-29 19:10:31 +01:00
"fmt"
2024-03-09 13:41:57 +01:00
"log/slog"
2023-12-29 19:10:31 +01:00
"os"
2024-01-20 14:33:58 +01:00
"os/signal"
"syscall"
2023-12-29 19:10:31 +01:00
2024-03-09 13:41:57 +01:00
"code.ewintr.nl/emdb/job"
"code.ewintr.nl/emdb/storage"
2024-01-20 11:02:00 +01:00
"github.com/tmc/langchaingo/chains"
2023-12-30 13:09:23 +01:00
"github.com/tmc/langchaingo/llms/ollama"
2024-01-20 11:02:00 +01:00
"github.com/tmc/langchaingo/prompts"
)
const (
mentionsTemplate = `The following text is a user comment about the movie {{.title}}. In it, the user may have referenced other movie titles. List them if you see any.
----
{{.review}}
----
2024-01-20 14:33:58 +01:00
If you found any movie titles other than {{.title}}, list them below in a JSON array. If there are other titles, like TV shows, books or games, ignore them. The format is as follows:
2024-01-20 11:02:00 +01:00
2024-01-20 14:33:58 +01:00
["movie title 1", "movie title 2"]
2024-01-20 11:02:00 +01:00
2024-01-20 14:33:58 +01:00
Just answer with the JSON and nothing else. If you don't see any other movie titles, just answer with an empty array.`
2023-12-29 19:10:31 +01:00
)
func main() {
2024-03-09 13:41:57 +01:00
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
dbHost := os.Getenv("EMDB_DB_HOST")
dbName := os.Getenv("EMDB_DB_NAME")
dbUser := os.Getenv("EMDB_DB_USER")
dbPassword := os.Getenv("EMDB_DB_PASSWORD")
pgConnStr := fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", dbHost, dbUser, dbPassword, dbName)
dbPostgres, err := storage.NewPostgres(pgConnStr)
if err != nil {
fmt.Printf("could not create new postgres repo: %s", err.Error())
os.Exit(1)
}
movieRepo := storage.NewMovieRepository(dbPostgres)
reviewRepo := storage.NewReviewRepository(dbPostgres)
jobQueue := job.NewJobQueue(dbPostgres, logger)
2024-01-20 11:19:15 +01:00
2024-03-09 13:41:57 +01:00
go Work(movieRepo, reviewRepo, jobQueue)
2024-01-20 11:36:05 +01:00
2024-01-20 14:33:58 +01:00
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
<-c
}
2024-01-20 11:36:05 +01:00
2024-03-09 13:41:57 +01:00
func Work(movieRepo *storage.MovieRepository, reviewRepo *storage.ReviewRepository, jobQueue *job.JobQueue) {
2024-01-20 14:33:58 +01:00
for {
2024-03-09 13:41:57 +01:00
j, err := jobQueue.Next()
2024-01-20 14:33:58 +01:00
if err != nil {
fmt.Println(err)
os.Exit(1)
}
2024-03-09 13:41:57 +01:00
review, err := reviewRepo.FindOne(j.ActionID)
2024-01-20 14:33:58 +01:00
if err != nil {
fmt.Println(err)
os.Exit(1)
}
2024-03-09 13:41:57 +01:00
movie, err := movieRepo.FindOne(review.MovieID)
2024-01-20 14:33:58 +01:00
if err != nil {
fmt.Println(err)
os.Exit(1)
}
llm, err := ollama.New(ollama.WithModel("mistral"))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
ctx := context.Background()
prompt := prompts.NewPromptTemplate(
mentionsTemplate,
[]string{"title", "review"},
)
llmChain := chains.NewLLMChain(llm, prompt)
movieTitle := movie.Title
if movie.EnglishTitle != "" && movie.EnglishTitle != movie.Title {
movieTitle = fmt.Sprintf("%s (English title: %s)", movieTitle, movie.EnglishTitle)
}
fmt.Printf("Processing review for movie: %s\n", movieTitle)
fmt.Printf("Review: %s\n", review.Review)
outputValues, err := chains.Call(ctx, llmChain, map[string]any{
"title": movieTitle,
"review": review.Review,
})
if err != nil {
fmt.Println(err)
os.Exit(1)
}
out, ok := outputValues[llmChain.OutputKey].(string)
if !ok {
fmt.Println("invalid chain return")
}
fmt.Println(out)
resp := struct {
Movies []string `json:"movies"`
TVShows []string `json:"tvShows"`
Games []string `json:"games"`
Books []string `json:"books"`
}{}
if err := json.Unmarshal([]byte(out), &resp); err != nil {
fmt.Printf("could not unmarshal llm response, skipping this one: %s", err)
os.Exit(1)
}
review.Titles = resp
2024-03-09 13:41:57 +01:00
if err := reviewRepo.Store(review); err != nil {
2024-01-20 14:33:58 +01:00
fmt.Printf("could not update review: %s\n", err)
os.Exit(1)
}
2023-12-30 13:09:23 +01:00
}
2023-12-29 19:10:31 +01:00
}