diff --git a/cmd/odidere/main.go b/cmd/odidere/main.go new file mode 100644 index 0000000..e2bb60d --- /dev/null +++ b/cmd/odidere/main.go @@ -0,0 +1,83 @@ +// Command odidere serves the odidere voice assistant API. +// It provides STT, LLM, and TTS orchestration via HTTP endpoints. +// See package service for the main orchestration logic and package +// config for configuration options. +package main + +import ( + "context" + "flag" + "log/slog" + "os" + "runtime/debug" + + "github.com/chimerical-llc/odidere/internal/config" + "github.com/chimerical-llc/odidere/internal/service" +) + +func main() { + var cfgPath = flag.String( + "c", "", "path to configuration file (required)", + ) + flag.Parse() + + var log = slog.New(slog.NewTextHandler( + os.Stderr, + &slog.HandlerOptions{ + AddSource: true, + Level: slog.LevelDebug, + }, + )) + if *cfgPath == "" { + log.Error("missing config path") + os.Exit(1) + } + + // Log build info. + bi, ok := debug.ReadBuildInfo() + if ok { + var commit, time string + for _, s := range bi.Settings { + switch s.Key { + case "vcs.revision": + commit = s.Value + case "vcs.time": + time = s.Value + } + } + log.Debug( + "odidered", + slog.Group( + "build", + slog.String("commit", commit), + slog.String("time", time), + ), + ) + } + + cfg, err := config.Load(*cfgPath) + if err != nil { + log.Error( + "failed to load config", + slog.Any("error", err), + ) + os.Exit(1) + } + + svc, err := service.New(cfg, log) + if err != nil { + log.Error( + "failed to create service", + slog.Any("error", err), + ) + os.Exit(1) + } + + if err := svc.Run(context.Background()); err != nil { + log.Error( + "failed to run", + slog.Any("error", err), + ) + os.Exit(1) + } +}