trigo / trigo-web /inc /config.ts
k-l-lambda's picture
Update trigo-web with VS People multiplayer mode
15f353f
/**
* Configuration Utilities
*
* Provides centralized access to environment variables for ONNX model paths
* and other configuration values.
*
* Works across different contexts:
* - Frontend (Vite): Uses import.meta.env.VITE_* variables
* - Backend/Tools (Node): Uses process.env.* variables with dotenv
*/
import * as path from "path";
import { fileURLToPath } from "url";
// Environment detection
const isNode = typeof process !== "undefined" && process.versions?.node;
const isBrowser = typeof window !== "undefined";
/**
* ONNX Session Options
*/
export interface OnnxSessionOptions {
executionProviders: string[];
intraOpNumThreads?: number;
interOpNumThreads?: number;
graphOptimizationLevel?: "disabled" | "basic" | "extended" | "all";
enableCpuMemArena?: boolean;
enableMemPattern?: boolean;
}
/**
* Get ONNX model paths
* Returns paths appropriate for the current environment
*/
export function getOnnxModelPaths(): {
evaluationModel: string;
treeModel: string;
} {
// Frontend (Vite environment)
if (isBrowser && typeof import.meta.env !== "undefined") {
const evaluationModel = import.meta.env.VITE_ONNX_EVALUATION_MODEL;
const treeModel = import.meta.env.VITE_ONNX_TREE_MODEL;
if (!evaluationModel || !treeModel) {
throw new Error("ONNX model paths not configured. Check VITE_ONNX_EVALUATION_MODEL and VITE_ONNX_TREE_MODEL in .env");
}
return { evaluationModel, treeModel };
}
// Backend/Tools (Node environment)
if (isNode) {
const evaluationModel = process.env.ONNX_EVALUATION_MODEL;
const treeModel = process.env.ONNX_TREE_MODEL;
if (!evaluationModel || !treeModel) {
throw new Error("ONNX model paths not configured. Check ONNX_EVALUATION_MODEL and ONNX_TREE_MODEL in .env");
}
return { evaluationModel, treeModel };
}
// Should not reach here
throw new Error("Unknown environment - cannot determine model paths");
}
/**
* Get ONNX session options from environment variables
* Returns session options with threading and optimization configuration
*/
export function getOnnxSessionOptions(): OnnxSessionOptions {
// Default values
const options: OnnxSessionOptions = {
executionProviders: ["cpu"],
graphOptimizationLevel: "all",
enableCpuMemArena: true,
enableMemPattern: true
};
// Frontend (Vite environment)
if (isBrowser && typeof import.meta.env !== "undefined") {
const intraThreadsEnv = import.meta.env.VITE_ONNX_INTRA_OP_NUM_THREADS;
const interThreadsEnv = import.meta.env.VITE_ONNX_INTER_OP_NUM_THREADS;
const graphOptEnv = import.meta.env.VITE_ONNX_GRAPH_OPTIMIZATION_LEVEL;
if (intraThreadsEnv) options.intraOpNumThreads = parseInt(intraThreadsEnv, 10);
if (interThreadsEnv) options.interOpNumThreads = parseInt(interThreadsEnv, 10);
if (graphOptEnv) options.graphOptimizationLevel = graphOptEnv as any;
}
// Backend/Tools (Node environment)
if (isNode) {
const intraThreadsEnv = process.env.ONNX_INTRA_OP_NUM_THREADS;
const interThreadsEnv = process.env.ONNX_INTER_OP_NUM_THREADS;
const graphOptEnv = process.env.ONNX_GRAPH_OPTIMIZATION_LEVEL;
const cpuMemArenaEnv = process.env.ONNX_ENABLE_CPU_MEM_ARENA;
const memPatternEnv = process.env.ONNX_ENABLE_MEM_PATTERN;
if (intraThreadsEnv) options.intraOpNumThreads = parseInt(intraThreadsEnv, 10);
if (interThreadsEnv) options.interOpNumThreads = parseInt(interThreadsEnv, 10);
if (graphOptEnv) options.graphOptimizationLevel = graphOptEnv as any;
if (cpuMemArenaEnv) options.enableCpuMemArena = cpuMemArenaEnv === "true";
if (memPatternEnv) options.enableMemPattern = memPatternEnv === "true";
}
return options;
}
/**
* Get absolute path to model file (Node.js only)
* Resolves relative paths to absolute paths from project root
*/
export function getAbsoluteModelPath(relativePath: string): string {
if (!isNode) {
return relativePath; // Browser environment - return as-is
}
// If already absolute, return as-is
if (path.isAbsolute(relativePath)) {
return relativePath;
}
// Resolve relative to project root
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const rootDir = path.resolve(__dirname, "..");
return path.resolve(rootDir, relativePath);
}
/**
* Load environment variables from .env file (Node.js only)
* Call this at the start of tool scripts
*
* Loading order:
* 1. .env (base configuration, committed to git)
* 2. .env.local (local overrides, not committed to git)
*/
export async function loadEnvConfig(): Promise<void> {
if (!isNode) {
console.warn("[Config] loadEnvConfig() called in non-Node environment");
return;
}
try {
// Dynamically import dotenv (ESM-compatible)
const dotenv = (await import("dotenv")).default;
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const rootDir = path.resolve(__dirname, "..");
// Load base .env file
const baseResult = dotenv.config({ path: path.join(rootDir, ".env") });
if (baseResult.error) {
console.warn("[Config] Failed to load .env:", baseResult.error.message);
} else {
console.log("[Config] ✓ Base environment variables loaded from .env");
}
// Load .env.local for local overrides (if exists)
// Use override: true to allow .env.local to override .env values
const localResult = dotenv.config({
path: path.join(rootDir, ".env.local"),
override: true
});
if (!localResult.error) {
console.log("[Config] ✓ Local overrides loaded from .env.local");
}
// Silently ignore if .env.local doesn't exist (optional file)
} catch (error) {
console.warn("[Config] dotenv not available:", error);
}
}