mirror of
https://github.com/eggent-ai/eggent.git
synced 2026-03-07 18:13:07 +00:00
111 lines
2.9 KiB
TypeScript
111 lines
2.9 KiB
TypeScript
import fs from "fs/promises";
|
|
import path from "path";
|
|
import { AppSettings } from "@/lib/types";
|
|
import {
|
|
DEFAULT_AUTH_PASSWORD_HASH,
|
|
DEFAULT_AUTH_USERNAME,
|
|
} from "@/lib/auth/password";
|
|
|
|
const DATA_DIR = path.join(process.cwd(), "data");
|
|
const SETTINGS_DIR = path.join(DATA_DIR, "settings");
|
|
const SETTINGS_FILE = path.join(SETTINGS_DIR, "settings.json");
|
|
|
|
async function ensureDir(dir: string) {
|
|
await fs.mkdir(dir, { recursive: true });
|
|
}
|
|
|
|
export const DEFAULT_SETTINGS: AppSettings = {
|
|
chatModel: {
|
|
provider: "openai",
|
|
model: "gpt-4o",
|
|
temperature: 0.7,
|
|
maxTokens: 4096,
|
|
},
|
|
utilityModel: {
|
|
provider: "openai",
|
|
model: "gpt-4o-mini",
|
|
temperature: 0.3,
|
|
maxTokens: 2048,
|
|
},
|
|
embeddingsModel: {
|
|
provider: "openai",
|
|
model: "text-embedding-3-small",
|
|
dimensions: 1536,
|
|
},
|
|
codeExecution: {
|
|
enabled: true,
|
|
timeout: 600,
|
|
maxOutputLength: 120000,
|
|
},
|
|
memory: {
|
|
enabled: true,
|
|
similarityThreshold: 0.35,
|
|
maxResults: 10,
|
|
chunkSize: 400,
|
|
},
|
|
search: {
|
|
enabled: false,
|
|
provider: "none",
|
|
},
|
|
general: {
|
|
darkMode: false,
|
|
language: "en",
|
|
},
|
|
auth: {
|
|
enabled: true,
|
|
username: DEFAULT_AUTH_USERNAME,
|
|
passwordHash: DEFAULT_AUTH_PASSWORD_HASH,
|
|
mustChangeCredentials: true,
|
|
},
|
|
};
|
|
|
|
export async function getSettings(): Promise<AppSettings> {
|
|
await ensureDir(SETTINGS_DIR);
|
|
try {
|
|
const content = await fs.readFile(SETTINGS_FILE, "utf-8");
|
|
const saved = JSON.parse(content) as unknown;
|
|
if (!saved || typeof saved !== "object" || Array.isArray(saved)) {
|
|
return structuredClone(DEFAULT_SETTINGS);
|
|
}
|
|
// Deep merge with defaults to handle new nested fields.
|
|
return deepMerge(
|
|
structuredClone(DEFAULT_SETTINGS) as unknown as Record<string, unknown>,
|
|
saved as Record<string, unknown>
|
|
) as unknown as AppSettings;
|
|
} catch {
|
|
return structuredClone(DEFAULT_SETTINGS);
|
|
}
|
|
}
|
|
|
|
export async function saveSettings(
|
|
settings: Partial<AppSettings>
|
|
): Promise<AppSettings> {
|
|
await ensureDir(SETTINGS_DIR);
|
|
const current = await getSettings();
|
|
const merged = deepMerge(current as unknown as Record<string, unknown>, settings as unknown as Record<string, unknown>) as unknown as AppSettings;
|
|
await fs.writeFile(SETTINGS_FILE, JSON.stringify(merged, null, 2), "utf-8");
|
|
return merged;
|
|
}
|
|
|
|
function deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {
|
|
const result = { ...target };
|
|
for (const key of Object.keys(source)) {
|
|
if (
|
|
source[key] &&
|
|
typeof source[key] === "object" &&
|
|
!Array.isArray(source[key]) &&
|
|
target[key] &&
|
|
typeof target[key] === "object" &&
|
|
!Array.isArray(target[key])
|
|
) {
|
|
result[key] = deepMerge(
|
|
target[key] as Record<string, unknown>,
|
|
source[key] as Record<string, unknown>
|
|
);
|
|
} else {
|
|
result[key] = source[key];
|
|
}
|
|
}
|
|
return result;
|
|
}
|