Spaces:
Runtime error
Runtime error
File size: 5,018 Bytes
857a91b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | package config
import (
"os"
"path/filepath"
"strconv"
"strings"
)
// Defaults returns a Config populated with mode-aware defaults.
func Defaults(mode Mode) *Config {
if !mode.Valid() {
mode = ModeLocalDev
}
maxConcurrent := 2
switch mode {
case ModeHFSpace:
maxConcurrent = 1
case ModeCustomerAgent, ModeCloudWorker:
maxConcurrent = 5
}
dataDir := "/var/lib/matrix-runtime"
if mode == ModeLocalDev {
if home, err := os.UserHomeDir(); err == nil {
dataDir = filepath.Join(home, ".matrix", "runtime", "data")
}
}
return &Config{
Mode: mode,
Port: 8080,
DataDir: dataDir,
MaxTTLSeconds: 600,
MaxConcurrentJobs: maxConcurrent,
InstallTimeoutSeconds: 120,
StartupTimeoutSeconds: 45,
RPCTimeoutSeconds: 20,
MaxLogBytes: 1024 * 1024,
CloudURL: "https://cloud.matrixhub.io",
HFCacheDir: filepath.Join(dataDir, "models", "huggingface"),
DBPath: filepath.Join(dataDir, "matrixcloud.db"),
DBSchema: "matrixcloud",
JobRetentionHours: 24,
LogRetentionHours: 72,
CleanupIntervalMinutes: 15,
RateLimitRPM: 120,
}
}
// FromEnv builds a Config from environment variables, layered on top of the
// mode-aware defaults. The mode is resolved from modeOverride (a CLI flag) when
// non-empty, otherwise from MATRIX_RUNTIME_MODE, otherwise local-dev.
func FromEnv(modeOverride string) *Config {
mode := Mode(firstNonEmpty(modeOverride, os.Getenv("MATRIX_RUNTIME_MODE"), string(ModeLocalDev)))
c := Defaults(mode)
// Honor MATRIX_RUNTIME_PORT, else the PaaS convention $PORT (Cloud Run,
// Render, Railway, Koyeb, Heroku, …) so hosted deploys work out of the box.
if v := firstNonEmpty(os.Getenv("MATRIX_RUNTIME_PORT"), os.Getenv("PORT")); v != "" {
if n, err := strconv.Atoi(v); err == nil {
c.Port = n
}
}
if v := os.Getenv("MATRIX_RUNTIME_DATA_DIR"); v != "" {
c.DataDir = v
c.HFCacheDir = filepath.Join(v, "models", "huggingface")
c.DBPath = filepath.Join(v, "matrixcloud.db")
}
if v := os.Getenv("MATRIX_RUNTIME_DB_PATH"); v != "" {
c.DBPath = v
}
if v := os.Getenv("MATRIX_RUNTIME_MAX_TTL_SECONDS"); v != "" {
if n, err := strconv.Atoi(v); err == nil && n > 0 {
c.MaxTTLSeconds = n
}
}
if v := os.Getenv("MATRIX_RUNTIME_MAX_CONCURRENT_JOBS"); v != "" {
if n, err := strconv.Atoi(v); err == nil && n > 0 {
c.MaxConcurrentJobs = n
}
}
c.RuntimeID = firstNonEmpty(os.Getenv("MATRIX_RUNTIME_ID"), c.RuntimeID)
c.Workspace = firstNonEmpty(os.Getenv("MATRIX_RUNTIME_WORKSPACE"), c.Workspace)
c.CloudURL = firstNonEmpty(os.Getenv("MATRIX_CLOUD_URL"), c.CloudURL)
c.JoinToken = firstNonEmpty(os.Getenv("MATRIX_RUNTIME_JOIN_TOKEN"), c.JoinToken)
c.APIToken = firstNonEmpty(os.Getenv("MATRIX_RUNTIME_API_TOKEN"), c.APIToken)
c.HFToken = firstNonEmpty(os.Getenv("HF_TOKEN"), c.HFToken)
if v := os.Getenv("MATRIX_RUNTIME_HF_CACHE_DIR"); v != "" {
c.HFCacheDir = v
}
// PostgreSQL/Neon connection for the hosted control plane. Several common
// env names are accepted; the first non-empty one wins. Never hardcode the
// DSN — it carries credentials and must come from the environment.
c.DatabaseURL = firstNonEmpty(
os.Getenv("MATRIXCLOUD_DATABASE_URL"),
os.Getenv("MATRIX_RUNTIME_DB_URL"),
os.Getenv("DATABASE_URL"),
)
c.DBSchema = firstNonEmpty(os.Getenv("MATRIXCLOUD_DB_SCHEMA"), c.DBSchema, "matrixcloud")
c.PublicURL = firstNonEmpty(os.Getenv("MATRIX_RUNTIME_PUBLIC_URL"), os.Getenv("MATRIXCLOUD_APP_URL"))
if n, ok := envInt("MATRIX_RUNTIME_JOB_RETENTION_HOURS"); ok {
c.JobRetentionHours = n
}
if n, ok := envInt("MATRIX_RUNTIME_LOG_RETENTION_HOURS"); ok {
c.LogRetentionHours = n
}
if n, ok := envInt("MATRIX_RUNTIME_CLEANUP_INTERVAL_MINUTES"); ok {
c.CleanupIntervalMinutes = n
}
if n, ok := envInt("MATRIX_RUNTIME_RATE_LIMIT_RPM"); ok {
c.RateLimitRPM = n
}
// MatrixShell executes commands in a local sandbox: safe-by-default means it
// is ON only in local-dev unless explicitly enabled. MATRIX_SHELL_ENABLED
// (or MATRIX_RUNTIME_MATRIXSHELL_ENABLED) overrides in either direction.
c.MatrixShellEnabled = mode == ModeLocalDev
if v := firstNonEmpty(os.Getenv("MATRIX_RUNTIME_MATRIXSHELL_ENABLED"), os.Getenv("MATRIX_SHELL_ENABLED")); v != "" {
c.MatrixShellEnabled = parseBool(v)
}
return c
}
// parseBool interprets common truthy/falsey strings; unknown values are false.
func parseBool(s string) bool {
switch strings.ToLower(strings.TrimSpace(s)) {
case "1", "true", "yes", "on", "enabled":
return true
default:
return false
}
}
// envInt reads an integer env var; ok is false when unset or unparseable.
func envInt(key string) (int, bool) {
v := os.Getenv(key)
if v == "" {
return 0, false
}
n, err := strconv.Atoi(v)
if err != nil {
return 0, false
}
return n, true
}
func firstNonEmpty(vals ...string) string {
for _, v := range vals {
if v != "" {
return v
}
}
return ""
}
|