package main import ( "context" "fmt" "io" "net/http" "os" "strings" "time" "github.com/descrybe/descrybe-v2/apps/api/internal/aiprovider" "github.com/descrybe/descrybe-v2/apps/api/internal/config" "github.com/descrybe/descrybe-v2/apps/api/internal/db" "github.com/descrybe/descrybe-v2/apps/api/internal/platformsettings" "github.com/descrybe/descrybe-v2/apps/api/internal/processing" "github.com/google/uuid" ) func main() { cfg, err := config.Load() if err != nil { fmt.Fprintf(os.Stderr, "config: %v\n", err); os.Exit(2) } ctx := context.Background() pool, err := db.NewPool(ctx, cfg.DatabaseURL, db.PoolOptions{ MaxConns: int32(cfg.DBMaxConns), MinConns: int32(cfg.DBMinConns), MaxConnLifetime: cfg.DBMaxConnLifetime, MaxConnLifetimeJitter: cfg.DBMaxConnLifetimeJitter, MaxConnIdleTime: cfg.DBMaxConnIdleTime, HealthCheckPeriod: cfg.DBHealthCheckPeriod, StatementTimeout: cfg.DBStatementTimeout, }) if err != nil { fmt.Fprintf(os.Stderr, "db: %v\n", err); os.Exit(2) } defer pool.Close() platEnv := platformsettings.EnvConfig{AppEncryptionKey: cfg.AppEncryptionKey, CredentialsEncryptionKey: cfg.CredentialsEncryptionKey, TokenSigningSecret: cfg.TokenSigningSecret, DatabaseURL: cfg.DatabaseURL, OpenAIAPIKey: cfg.OpenAIAPIKey, OpenAIBaseURL: cfg.OpenAIBaseURL, OpenAIModel: cfg.OpenAIModel} plat := platformsettings.NewService(pool, platEnv) ai := aiprovider.NewService(pool, aiprovider.EnvConfig{AppEncryptionKey: cfg.AppEncryptionKey, CredentialsEncryptionKey: cfg.CredentialsEncryptionKey, TokenSigningSecret: cfg.TokenSigningSecret, DatabaseURL: cfg.DatabaseURL, OpenAIAPIKey: cfg.OpenAIAPIKey, OpenAIBaseURL: cfg.OpenAIBaseURL, OpenAIModel: cfg.OpenAIModel}) ai.Platform = plat companyID := uuid.MustParse("604f23a8-b66e-4b21-8b45-0d72b68f4790") roleCfg, err := plat.ResolveAIConfig(ctx, platformsettings.AIRoleProcessing) if err != nil { fmt.Fprintf(os.Stderr, "ResolveAIConfig: %v\n", err); os.Exit(2) } completer, mode, byok, err := ai.ResolveCompleterForRole(ctx, companyID, aiprovider.RoleProcessing) if err != nil { fmt.Fprintf(os.Stderr, "ResolveCompleter: %v\n", err); os.Exit(2) } client, ok := completer.(*processing.OpenAIClient) if !ok { fmt.Fprintf(os.Stderr, "not OpenAIClient: %T\n", completer); os.Exit(2) } base := strings.TrimRight(strings.TrimSpace(client.BaseURL), "/") modelsURL := base + "/models" fmt.Printf("source=%s provider=%s base=%s model=%s mode=%s byok=%v key_len=%d\n", roleCfg.Source, roleCfg.Provider, base, client.Model, mode, byok, len(client.APIKey)) if processing.IsMockOrLoopbackBaseURL(base) { fmt.Println("FAIL mock/loopback"); os.Exit(3) } req, _ := http.NewRequestWithContext(ctx, http.MethodGet, modelsURL, nil) req.Header.Set("Authorization", "Bearer "+client.APIKey) req.Header.Set("Accept", "application/json") start := time.Now() resp, err := http.DefaultClient.Do(req) elapsed := time.Since(start).Round(time.Millisecond) if err != nil { fmt.Printf("models_error=%v elapsed=%s\n", err, elapsed); os.Exit(4) } body, _ := io.ReadAll(io.LimitReader(resp.Body, 512)) resp.Body.Close() snip := strings.TrimSpace(string(body)) if len(snip) > 160 { snip = snip[:160]+"…" } fmt.Printf("models_http=%d elapsed=%s snippet=%q\n", resp.StatusCode, elapsed, snip) if resp.StatusCode == 502 { os.Exit(5) } if resp.StatusCode != 200 && resp.StatusCode != 401 { os.Exit(6) } os.Exit(0) }