97 lines
3.7 KiB
TypeScript
97 lines
3.7 KiB
TypeScript
import { registerAs } from "@nestjs/config";
|
|
|
|
const normalizeAiProvider = (): "ollama" | "claude" | "openai" => {
|
|
const provider = process.env.AI_PROVIDER?.trim().toLowerCase();
|
|
|
|
if (!provider) {
|
|
return "ollama";
|
|
}
|
|
|
|
if (provider !== "ollama" && provider !== "claude" && provider !== "openai") {
|
|
return "ollama";
|
|
}
|
|
|
|
return provider;
|
|
};
|
|
|
|
const parseValkeyUrl = (url: string): { host?: string; port?: number; password?: string } => {
|
|
try {
|
|
const parsed = new URL(url);
|
|
const port = parsed.port ? parseInt(parsed.port, 10) : undefined;
|
|
|
|
return {
|
|
host: parsed.hostname || undefined,
|
|
port: Number.isNaN(port) ? undefined : port,
|
|
password: parsed.password ? decodeURIComponent(parsed.password) : undefined,
|
|
};
|
|
} catch {
|
|
return {};
|
|
}
|
|
};
|
|
|
|
export const orchestratorConfig = registerAs("orchestrator", () => {
|
|
const valkeyUrl = process.env.VALKEY_URL ?? "redis://localhost:6379";
|
|
const parsedValkeyUrl = parseValkeyUrl(valkeyUrl);
|
|
|
|
return {
|
|
host: process.env.HOST ?? process.env.BIND_ADDRESS ?? "127.0.0.1",
|
|
port: parseInt(process.env.ORCHESTRATOR_PORT ?? "3001", 10),
|
|
valkey: {
|
|
host: process.env.VALKEY_HOST ?? parsedValkeyUrl.host ?? "localhost",
|
|
port: parseInt(process.env.VALKEY_PORT ?? String(parsedValkeyUrl.port ?? 6379), 10),
|
|
password: process.env.VALKEY_PASSWORD ?? parsedValkeyUrl.password,
|
|
url: valkeyUrl,
|
|
connectTimeout: parseInt(process.env.VALKEY_CONNECT_TIMEOUT_MS ?? "5000", 10),
|
|
commandTimeout: parseInt(process.env.VALKEY_COMMAND_TIMEOUT_MS ?? "3000", 10),
|
|
},
|
|
claude: {
|
|
apiKey: process.env.CLAUDE_API_KEY,
|
|
},
|
|
aiProvider: normalizeAiProvider(),
|
|
docker: {
|
|
socketPath: process.env.DOCKER_SOCKET ?? "/var/run/docker.sock",
|
|
},
|
|
git: {
|
|
userName: process.env.GIT_USER_NAME ?? "Mosaic Orchestrator",
|
|
userEmail: process.env.GIT_USER_EMAIL ?? "orchestrator@mosaicstack.dev",
|
|
},
|
|
killswitch: {
|
|
enabled: process.env.KILLSWITCH_ENABLED === "true",
|
|
},
|
|
sandbox: {
|
|
enabled: process.env.SANDBOX_ENABLED !== "false",
|
|
defaultImage: process.env.SANDBOX_DEFAULT_IMAGE ?? "node:20-alpine",
|
|
defaultMemoryMB: parseInt(process.env.SANDBOX_DEFAULT_MEMORY_MB ?? "256", 10),
|
|
defaultCpuLimit: parseFloat(process.env.SANDBOX_DEFAULT_CPU_LIMIT ?? "1.0"),
|
|
networkMode: process.env.SANDBOX_NETWORK_MODE ?? "none",
|
|
},
|
|
coordinator: {
|
|
url: process.env.COORDINATOR_URL ?? "http://localhost:8000",
|
|
timeout: parseInt(process.env.COORDINATOR_TIMEOUT_MS ?? "30000", 10),
|
|
retries: parseInt(process.env.COORDINATOR_RETRIES ?? "3", 10),
|
|
apiKey: process.env.COORDINATOR_API_KEY,
|
|
},
|
|
yolo: {
|
|
enabled: process.env.YOLO_MODE === "true",
|
|
},
|
|
spawner: {
|
|
maxConcurrentAgents: parseInt(process.env.MAX_CONCURRENT_AGENTS ?? "2", 10),
|
|
sessionCleanupDelayMs: parseInt(process.env.SESSION_CLEANUP_DELAY_MS ?? "30000", 10),
|
|
},
|
|
queue: {
|
|
name: process.env.ORCHESTRATOR_QUEUE_NAME ?? "orchestrator-tasks",
|
|
maxRetries: parseInt(process.env.ORCHESTRATOR_QUEUE_MAX_RETRIES ?? "3", 10),
|
|
baseDelay: parseInt(process.env.ORCHESTRATOR_QUEUE_BASE_DELAY_MS ?? "1000", 10),
|
|
maxDelay: parseInt(process.env.ORCHESTRATOR_QUEUE_MAX_DELAY_MS ?? "60000", 10),
|
|
concurrency: parseInt(process.env.ORCHESTRATOR_QUEUE_CONCURRENCY ?? "1", 10),
|
|
completedRetentionCount: parseInt(process.env.QUEUE_COMPLETED_RETENTION_COUNT ?? "100", 10),
|
|
completedRetentionAgeSeconds: parseInt(
|
|
process.env.QUEUE_COMPLETED_RETENTION_AGE_S ?? "3600",
|
|
10
|
|
),
|
|
failedRetentionCount: parseInt(process.env.QUEUE_FAILED_RETENTION_COUNT ?? "1000", 10),
|
|
failedRetentionAgeSeconds: parseInt(process.env.QUEUE_FAILED_RETENTION_AGE_S ?? "86400", 10),
|
|
},
|
|
};
|
|
});
|