Files
ModelRouter/cmd/llmsproxy/main.go

63 lines
1.9 KiB
Go

// Command llmsproxy is a standalone gateway that exposes multiple upstream LLM
// sources behind a unified OpenAI-compatible HTTP API. Protocol differences are
// handled by Lua adapters (per source), optionally signing outgoing requests.
// It supports explicit model selection or AUTO routing by priority, image
// generation, multimodal payloads, a web UI for adapter/source management, and
// concurrent/queued scheduling with backoff and failover.
package main
import (
"flag"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"llmsproxy/internal/core"
"llmsproxy/internal/gateway"
)
func main() {
cfgPath := flag.String("config", "config.yaml", "path to gateway config file")
flag.Parse()
c, err := core.New(*cfgPath)
if err != nil {
log.Fatalf("[llmsproxy] core: %v", err)
}
defer c.Close()
gw, err := gateway.New(c, c.GatewayKeys())
if err != nil {
log.Fatalf("[llmsproxy] gateway: %v", err)
}
srv := &http.Server{
Addr: c.Listen(),
Handler: gw.Handler(),
ReadHeaderTimeout: 10 * time.Second,
}
go func() {
cert, key := c.TLS()
if cert != "" && key != "" {
log.Printf("[llmsproxy] listening HTTPS on %s (cert=%q) (default_model=%s, models=%v, adapters=%d)",
c.Listen(), cert, c.DefaultModel(), c.Registry().ModelList(), len(c.ListAdapters()))
if err := srv.ListenAndServeTLS(cert, key); err != nil && err != http.ErrServerClosed {
log.Fatalf("[llmsproxy] server: %v", err)
}
return
}
log.Printf("[llmsproxy] listening HTTP on %s (default_model=%s, models=%v, adapters=%d)",
c.Listen(), c.DefaultModel(), c.Registry().ModelList(), len(c.ListAdapters()))
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("[llmsproxy] server: %v", err)
}
}()
stop := make(chan os.Signal, 1)
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
<-stop
log.Printf("[llmsproxy] shutting down")
}