Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var Command = &cli.Command{ Name: "serve", Flags: []cli.Flag{ &cli.StringFlag{ Name: "port", Value: "8089", Usage: "port to listen on", Aliases: []string{"p"}, Sources: cli.EnvVars("PORT"), }, &cli.StringFlag{ Name: "turso-db-url", Sources: cli.EnvVars("TURSO_CONNECTION_PATH"), }, &cli.StringFlag{ Name: "turso-db-token", Sources: cli.EnvVars("TURSO_CONNECTION_TOKEN"), }, }, Action: func(ctx context.Context, cmd *cli.Command) error { gormDB, err := setupDatabase(cmd.String("turso-db-url"), cmd.String("turso-db-token")) if err != nil { return fmt.Errorf("failed to setup database: %w", err) } productIDs := map[apiv1.CheckoutProduct]string{ apiv1.CheckoutProduct_CHECKOUT_PRODUCT_PLUS: os.Getenv("POLAR_PRODUCT_PLUS_ID"), apiv1.CheckoutProduct_CHECKOUT_PRODUCT_PRO: os.Getenv("POLAR_PRODUCT_PRO_ID"), } apiService, err := api.NewServiceImpl(gormDB, productIDs) if err != nil { return fmt.Errorf("failed to create api service: %w", err) } mux := http.NewServeMux() apiPath, apiHandler := apiv1connect.NewApiServiceHandler(apiService, connect.WithInterceptors( api.NewAuthInterceptor(gormDB), validate.NewInterceptor(), )) protocols := new(http.Protocols) protocols.SetHTTP1(true) protocols.SetUnencryptedHTTP2(true) mux.Handle(apiPath, apiHandler) webhookPath := "/api/v1/webhooks/polar" mux.HandleFunc(webhookPath, api.NewPolarWebhookHandler(apiService)) slog.Info("serving polar webhook handler", "path", webhookPath) geminiProxyConfig := llmProxyConfig{ Provider: "gemini", BaseURL: "https://generativelanguage.googleapis.com", PathPrefix: "/api/v1/gemini", SetupRequest: func(_ *http.Request, targetURL *url.URL, _ *http.Request) error { apiKey := os.Getenv("GEMINI_API_KEY") if apiKey == "" { return fmt.Errorf("missing GEMINI_API_KEY") } query := targetURL.Query() query.Set("key", apiKey) targetURL.RawQuery = query.Encode() return nil }, ExtractUsage: extractGeminiUsageMetadata, } openAIProxyConfig := llmProxyConfig{ Provider: "openai", BaseURL: "https://api.openai.com", PathPrefix: "/api/v1/openai", SetupRequest: func(_ *http.Request, _ *url.URL, proxyReq *http.Request) error { apiKey := os.Getenv("OPENAI_API_KEY") if apiKey == "" { return fmt.Errorf("missing OPENAI_API_KEY") } proxyReq.Header.Set("Authorization", "Bearer "+apiKey) return nil }, ExtractUsage: extractOpenAIUsageMetadata, } anthropicProxyConfig := llmProxyConfig{ Provider: "anthropic", BaseURL: "https://api.anthropic.com", PathPrefix: "/api/v1/anthropic", SetupRequest: func(_ *http.Request, _ *url.URL, proxyReq *http.Request) error { apiKey := os.Getenv("ANTHROPIC_API_KEY") if apiKey == "" { return fmt.Errorf("missing ANTHROPIC_API_KEY") } version := os.Getenv("ANTHROPIC_VERSION") if version == "" { version = "2023-06-01" } proxyReq.Header.Set("x-api-key", apiKey) proxyReq.Header.Set("anthropic-version", version) if proxyReq.Header.Get("Content-Type") == "" { proxyReq.Header.Set("Content-Type", "application/json") } return nil }, ExtractUsage: extractAnthropicUsageMetadata, } grokProxyConfig := llmProxyConfig{ Provider: "grok", BaseURL: "https://api.x.ai", PathPrefix: "/api/v1/grok", SetupRequest: func(_ *http.Request, _ *url.URL, proxyReq *http.Request) error { apiKey := os.Getenv("GROK_API_KEY") if apiKey == "" { return fmt.Errorf("missing GROK_API_KEY") } proxyReq.Header.Set("Authorization", "Bearer "+apiKey) return nil }, ExtractUsage: extractGrokUsageMetadata, } geminiProxyPath := "/api/v1/gemini/" mux.HandleFunc(geminiProxyPath, newLLMProxyHandler(gormDB, geminiProxyConfig)) slog.Info("serving gemini proxy handler", "path", geminiProxyPath) openAIProxyPath := "/api/v1/openai/" mux.HandleFunc(openAIProxyPath, newLLMProxyHandler(gormDB, openAIProxyConfig)) slog.Info("serving openai proxy handler", "path", openAIProxyPath) anthropicProxyPath := "/api/v1/anthropic/" mux.HandleFunc(anthropicProxyPath, newLLMProxyHandler(gormDB, anthropicProxyConfig)) slog.Info("serving anthropic proxy handler", "path", anthropicProxyPath) grokProxyPath := "/api/v1/grok/" mux.HandleFunc(grokProxyPath, newLLMProxyHandler(gormDB, grokProxyConfig)) slog.Info("serving grok proxy handler", "path", grokProxyPath) slog.Info("serving rpc handler for api v1 service", "path", apiPath) h2Handler := h2c.NewHandler(mux, &http2.Server{}) server := &http.Server{ Addr: ":" + cmd.String("port"), Handler: h2Handler, ReadHeaderTimeout: 3 * time.Second, Protocols: protocols, } sigint := make(chan os.Signal, 1) signal.Notify(sigint, os.Interrupt) go func() { slog.Info("serving http server for api v1 service", "addr", ":"+cmd.String("port")) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { slog.Error("failed to serve engine service", "error", err) os.Exit(1) } }() <-sigint slog.Info("shutting down engine service") shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := server.Shutdown(shutdownCtx); err != nil { slog.Error("server forced to shutdown", "error", err) } slog.Info("engine service shut down") return nil }, }
Functions ¶
This section is empty.
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.