This commit is contained in:
2026-08-17 09:33:07 +02:00
parent 0dceb3a404
commit fe94c2fb9c
40 changed files with 2360 additions and 340 deletions
+59
View File
@@ -0,0 +1,59 @@
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)
}