Spaces:
Sleeping
Sleeping
| /** | |
| * Runtime configuration — persistent feature toggles that can be flipped from | |
| * the dashboard at runtime without a restart or editing .env. Backed by a | |
| * small JSON file next to the project root so it survives redeploys. | |
| * | |
| * Currently hosts the "experimental" feature flags. Keep this tiny: anything | |
| * that needs a restart should stay in config.js / .env. | |
| */ | |
| import { readFileSync, writeFileSync, existsSync } from 'fs'; | |
| import { resolve, dirname } from 'path'; | |
| import { fileURLToPath } from 'url'; | |
| import { log } from './config.js'; | |
| const __dirname = dirname(fileURLToPath(import.meta.url)); | |
| const FILE = resolve(__dirname, '..', 'runtime-config.json'); | |
| export const DEFAULT_IDENTITY_PROMPTS = { | |
| anthropic: 'You are {model}, a large language model created by Anthropic. You are helpful, harmless, and honest. When asked about your identity or which model you are, you respond that you are {model}, made by Anthropic.', | |
| openai: 'You are {model}, a large language model created by OpenAI. When asked about your identity, you respond that you are {model}, made by OpenAI.', | |
| google: 'You are {model}, a large language model created by Google. When asked about your identity, you respond that you are {model}, made by Google.', | |
| deepseek: 'You are {model}, a large language model created by DeepSeek. When asked about your identity, you respond that you are {model}, made by DeepSeek.', | |
| xai: 'You are {model}, a large language model created by xAI. When asked about your identity, you respond that you are {model}, made by xAI.', | |
| alibaba: 'You are {model}, a large language model created by Alibaba. When asked about your identity, you respond that you are {model}, made by Alibaba.', | |
| moonshot: 'You are {model}, a large language model created by Moonshot AI. When asked about your identity, you respond that you are {model}, made by Moonshot AI.', | |
| zhipu: 'You are {model}, a large language model created by Zhipu AI. When asked about your identity, you respond that you are {model}, made by Zhipu AI.', | |
| minimax: 'You are {model}, a large language model created by MiniMax. When asked about your identity, you respond that you are {model}, made by MiniMax.', | |
| windsurf: 'You are {model}, a coding assistant model by Windsurf. When asked about your identity, you respond that you are {model}, made by Windsurf.', | |
| }; | |
| const DEFAULTS = { | |
| experimental: { | |
| // Reuse Cascade cascade_id across multi-turn requests when the history | |
| // fingerprint matches. Big latency win for long conversations but relies | |
| // on Windsurf keeping the cascade alive — off by default. | |
| cascadeConversationReuse: false, | |
| // Inject a system prompt that tells the model to identify itself as the | |
| // requested model (e.g. "You are Claude Opus 4.6, made by Anthropic") | |
| // instead of revealing the Windsurf/Cascade backend. Enabled by default | |
| // so API responses match official Claude/GPT behaviour. | |
| modelIdentityPrompt: true, | |
| // Pre-flight rate limit check via server.codeium.com before sending a | |
| // chat request. Reduces wasted attempts when the account has no message | |
| // capacity. Adds one network round-trip per attempt so off by default. | |
| preflightRateLimit: false, | |
| }, | |
| // Per-provider identity prompt templates. Use {model} as the model-name | |
| // placeholder. Edits from the dashboard are persisted here. | |
| identityPrompts: { ...DEFAULT_IDENTITY_PROMPTS }, | |
| }; | |
| function deepMerge(base, override) { | |
| if (!override || typeof override !== 'object') return base; | |
| const out = { ...base }; | |
| for (const [k, v] of Object.entries(override)) { | |
| if (v && typeof v === 'object' && !Array.isArray(v)) { | |
| out[k] = deepMerge(base[k] || {}, v); | |
| } else { | |
| out[k] = v; | |
| } | |
| } | |
| return out; | |
| } | |
| let _state = structuredClone(DEFAULTS); | |
| function load() { | |
| if (!existsSync(FILE)) return; | |
| try { | |
| const raw = JSON.parse(readFileSync(FILE, 'utf-8')); | |
| _state = deepMerge(DEFAULTS, raw); | |
| } catch (e) { | |
| log.warn(`runtime-config: failed to load ${FILE}: ${e.message}`); | |
| } | |
| } | |
| function persist() { | |
| try { | |
| writeFileSync(FILE, JSON.stringify(_state, null, 2)); | |
| } catch (e) { | |
| log.warn(`runtime-config: failed to persist: ${e.message}`); | |
| } | |
| } | |
| load(); | |
| export function getRuntimeConfig() { | |
| return structuredClone(_state); | |
| } | |
| export function getExperimental() { | |
| return { ...(_state.experimental || {}) }; | |
| } | |
| export function isExperimentalEnabled(key) { | |
| return !!_state.experimental?.[key]; | |
| } | |
| export function setExperimental(patch) { | |
| if (!patch || typeof patch !== 'object') return getExperimental(); | |
| _state.experimental = { ...(_state.experimental || {}), ...patch }; | |
| // Coerce to booleans — the dashboard ships JSON but we never want truthy | |
| // strings sneaking in as "true". | |
| for (const k of Object.keys(_state.experimental)) { | |
| _state.experimental[k] = !!_state.experimental[k]; | |
| } | |
| persist(); | |
| return getExperimental(); | |
| } | |
| export function getIdentityPrompts() { | |
| return { ...DEFAULT_IDENTITY_PROMPTS, ...(_state.identityPrompts || {}) }; | |
| } | |
| export function getIdentityPromptFor(provider) { | |
| const all = getIdentityPrompts(); | |
| return all[provider] || null; | |
| } | |
| export function setIdentityPrompts(patch) { | |
| if (!patch || typeof patch !== 'object') return getIdentityPrompts(); | |
| const current = _state.identityPrompts || {}; | |
| for (const [k, v] of Object.entries(patch)) { | |
| if (typeof v !== 'string') continue; | |
| current[k] = v.trim(); | |
| } | |
| _state.identityPrompts = current; | |
| persist(); | |
| return getIdentityPrompts(); | |
| } | |
| export function resetIdentityPrompt(provider) { | |
| if (provider && _state.identityPrompts) { | |
| delete _state.identityPrompts[provider]; | |
| } else { | |
| _state.identityPrompts = {}; | |
| } | |
| persist(); | |
| return getIdentityPrompts(); | |
| } | |