const INTENTS = new Set([ "casual", "factual", "support", "explain_internal", "admin_task", "codex_task", "feedback_export", "debug", "unknown" ]); const COMPLEXITIES = new Set(["fast", "normal", "expanded", "unlimited"]); const OKF_DEPTHS = new Set(["none", "light", "deep"]); const ANSWER_STYLES = new Set(["compact", "normal", "detailed", "json_only"]); const SOURCE_DEFAULTS = Object.freeze({ webui: { hard_chars: null, target_chars: 2500, allow_sections: true, allow_long_answer: true, allow_split: false }, discord: { hard_chars: 1900, target_chars: 1200, allow_sections: true, allow_long_answer: false, allow_split: false }, twitch: { hard_chars: 450, target_chars: 320, allow_sections: false, allow_long_answer: false, allow_split: false }, youtube: { hard_chars: 1800, target_chars: 900, allow_sections: false, allow_long_answer: false, allow_split: false }, kick: { hard_chars: 450, target_chars: 320, allow_sections: false, allow_long_answer: false, allow_split: false }, other: { hard_chars: 1000, target_chars: 700, allow_sections: false, allow_long_answer: false, allow_split: false } }); const MODE_BUDGETS = Object.freeze({ fast: 1024, normal: 4096, expanded: 8192, unlimited: 16384 }); function buildControllerDecision({ message = "", role = "user", scope = "assistant", originContext = null, gateDecision = null, requestClass = "simple_answer", config = {} } = {}) { const text = String(gateDecision?.message || message || ""); const source = sourceKey(originContext); const signals = detectSignals(text, role, scope); const lowConfidenceGate = gateDecision && ( gateDecision.confidence < 0.5 || /(?:low_confidence|timeout|error|invalid|unsafe|escalated)/i.test(gateDecision.reason_code || "") ); let intent = intentFromSignals(signals, requestClass); let complexity = complexityFromSignals(signals, requestClass, role); let okfRetrieval = okfDepthFromSignals(signals, complexity); let answerStyle = answerStyleFromSignals(signals, complexity, source); if (lowConfidenceGate && complexity === "fast") { complexity = "normal"; okfRetrieval = okfRetrieval === "none" && signals.needsOkf ? "light" : okfRetrieval; } if (gateDecision?.forced && complexity === "fast") { complexity = "normal"; } if (signals.adminOnly && role !== "admin" && complexity === "unlimited") { complexity = "expanded"; } const decision = normalizeControllerDecision({ schema: "lumi.ai.controller.v1", route: gateDecision?.route || "main_llm", intent, complexity, okf_retrieval: okfRetrieval, answer_style: answerStyle, source_scoped: true, source_profile: buildSourceProfile(source, config), permission_sensitive: signals.permissionSensitive, admin_only: signals.adminOnly, risk_of_private_data: signals.privateDataRisk, confidence: gateDecision ? gateDecision.confidence : confidenceFromSignals(signals), reason_code: controllerReason(signals, gateDecision, lowConfidenceGate), legacy_request_class: requestClass, gate_reason_code: gateDecision?.reason_code || null, fallback_used: Boolean(lowConfidenceGate) }); return decision; } function normalizeControllerDecision(value = {}) { const sourceProfile = value.source_profile && typeof value.source_profile === "object" ? value.source_profile : SOURCE_DEFAULTS.other; const requestedSource = String(sourceProfile.source || "other").toLowerCase(); const source = SOURCE_DEFAULTS[requestedSource] ? requestedSource : "other"; const fallbackProfile = SOURCE_DEFAULTS[source]; return { schema: "lumi.ai.controller.v1", route: ["main_llm", "refusal", "unavailable", "cached_answer", "predefined_answer"].includes(value.route) ? value.route : "main_llm", intent: INTENTS.has(value.intent) ? value.intent : "unknown", complexity: COMPLEXITIES.has(value.complexity) ? value.complexity : "normal", okf_retrieval: OKF_DEPTHS.has(value.okf_retrieval) ? value.okf_retrieval : "light", answer_style: ANSWER_STYLES.has(value.answer_style) ? value.answer_style : "normal", source_scoped: value.source_scoped !== false, source_profile: { source, hard_chars: sourceProfile.hard_chars === null || sourceProfile.hard_chars === undefined ? fallbackProfile.hard_chars : clampChars(sourceProfile.hard_chars, fallbackProfile.hard_chars || 1000), target_chars: clampChars(sourceProfile.target_chars, fallbackProfile.target_chars), allow_sections: Boolean(sourceProfile.allow_sections), allow_long_answer: Boolean(sourceProfile.allow_long_answer), allow_split: Boolean(sourceProfile.allow_split) }, permission_sensitive: Boolean(value.permission_sensitive), admin_only: Boolean(value.admin_only), risk_of_private_data: Boolean(value.risk_of_private_data), confidence: Math.max(0, Math.min(1, Number(value.confidence) || 0)), reason_code: /^[a-z0-9_]{2,80}$/.test(String(value.reason_code || "")) ? value.reason_code : "controller_normalized", legacy_request_class: String(value.legacy_request_class || "simple_answer"), gate_reason_code: value.gate_reason_code ? String(value.gate_reason_code).slice(0, 100) : null, fallback_used: Boolean(value.fallback_used) }; } function outputBudgetForController({ config = {}, requestClass = "simple_answer", explicitMaxTokens = null, controllerDecision = null } = {}) { const requested = Number(explicitMaxTokens); if (Number.isFinite(requested) && requested > 0) return clampBudget(requested); const mode = controllerDecision?.complexity || modeFromRequestClass(requestClass); const modeBudget = Number(MODE_BUDGETS[mode]); if (Number.isFinite(modeBudget) && modeBudget > 0) return clampBudget(modeBudget); const classBudget = Number(config.output_budgets?.[requestClass]); if (Number.isFinite(classBudget) && classBudget > 0) return clampBudget(classBudget); const fallback = Number(config.max_output_tokens); return clampBudget(Number.isFinite(fallback) && fallback > 0 ? fallback : 512); } function okfLimitForController(decision) { if (!decision || decision.okf_retrieval === "none") return 0; if (decision.okf_retrieval === "deep") return decision.complexity === "expanded" || decision.complexity === "unlimited" ? 5 : 4; return 2; } function buildSourceProfile(source, config = {}) { const key = SOURCE_DEFAULTS[source] ? source : "other"; const configured = config.source_profiles?.[key] || {}; const merged = { ...SOURCE_DEFAULTS[key], ...configured, source: key }; return { source: key, hard_chars: merged.hard_chars === null || merged.hard_chars === undefined ? null : Math.max(100, Math.min(12000, Number(merged.hard_chars) || SOURCE_DEFAULTS[key].hard_chars || 1000)), target_chars: Math.max(100, Math.min(12000, Number(merged.target_chars) || SOURCE_DEFAULTS[key].target_chars)), allow_sections: merged.allow_sections !== false, allow_long_answer: merged.allow_long_answer === true, allow_split: merged.allow_split === true }; } function detectSignals(message, role, scope) { const text = String(message || ""); const routeOrApi = /\b(?:GET|POST|PUT|PATCH|DELETE|OPTIONS|HEAD)\s+\/[^\s]+/i.test(text) || /\b(?:route|webroute|web route|endpoint|request|api)\b[\s\S]{0,80}\/[a-z0-9_/-]+/i.test(text) || /\/(?:admin|api|setup|auth|plugins|commands|feedback|stats|pages)(?:\/[a-z0-9_/-]*)?\b/i.test(text); const lumiInternal = /\b(lumi|webui|route|endpoint|api|plugin|okf|settings?|setup|wizard|admin page|moderator|permission|config|configuration|update|dashboard|navigation)\b/i.test(text) || routeOrApi; const codex = /\b(codex|taskfile|task file|implementation plan|acceptance criteria|validation steps|json output)\b/i.test(text); const feedbackExport = /\b(feedback.*export|export.*feedback|feedback-to-codex|internal-feedback-to-codex-taskfile)\b/i.test(text); const debug = /\b(debug|diagnos|troubleshoot|stack trace|runtime|backend|database|logs?|metrics?|failed|failure|error|exception)\b/i.test(text); const security = /\b(security|permission|private|secret|token|password|credential|audit|rbac|role|admin-only|sensitive)\b/i.test(text); const unlimited = role === "admin" && /\b(large-scale|architecture analysis|security audit|incident investigation|major migration|major refactor|comprehensive report|extensive synthesis|full system review)\b/i.test(text); const support = /\b(how do i|how to|what does|tell me about|explain|configure|set up|setup|support|help with|why does)\b/i.test(text); const knowledgeLookup = isSimpleKnowledgeLookup(text); const casual = text.split(/\s+/).length <= 18 && !lumiInternal && !debug && !codex && !security && !knowledgeLookup; return { routeOrApi, lumiInternal, knowledgeLookup, needsOkf: lumiInternal || support || debug || codex || feedbackExport || knowledgeLookup, codex, feedbackExport, debug, security, unlimited, support, casual, permissionSensitive: security || /\b(admin|moderator|mod|permission|role|private)\b/i.test(text), adminOnly: role === "admin" && (debug || security || unlimited || scope === "model_test"), privateDataRisk: security || /\b(my|mine|our|token|secret|password|credential|user id|database)\b/i.test(text) }; } function intentFromSignals(signals, requestClass) { if (signals.feedbackExport) return "feedback_export"; if (signals.codex) return "codex_task"; if (signals.debug) return "debug"; if (signals.security || signals.adminOnly) return "admin_task"; if (signals.lumiInternal) return "explain_internal"; if (signals.knowledgeLookup) return "factual"; if (signals.support) return "support"; if (requestClass === "navigation_help") return "support"; if (signals.casual) return "casual"; return "factual"; } function complexityFromSignals(signals, requestClass, role) { if (signals.unlimited) return "unlimited"; if (signals.codex || signals.feedbackExport || signals.debug || signals.security || requestClass === "admin_debug" || requestClass === "explicit_long") { return "expanded"; } if (signals.knowledgeLookup) return "fast"; if (signals.lumiInternal || signals.support || requestClass === "code_custom_command") return "normal"; if (signals.casual && role !== "admin") return "fast"; return "normal"; } function okfDepthFromSignals(signals, complexity) { if (!signals.needsOkf) return "none"; if (complexity === "expanded" || complexity === "unlimited" || signals.routeOrApi || signals.debug) return "deep"; return "light"; } function answerStyleFromSignals(signals, complexity, source) { if (signals.codex || signals.feedbackExport) return "json_only"; if (complexity === "expanded" || complexity === "unlimited") return "detailed"; if (source === "twitch" || source === "kick") return "compact"; return "normal"; } function confidenceFromSignals(signals) { if (signals.routeOrApi || signals.codex || signals.feedbackExport || signals.debug) return 0.9; if (signals.knowledgeLookup) return 0.82; if (signals.lumiInternal || signals.support) return 0.8; if (signals.casual) return 0.75; return 0.6; } function controllerReason(signals, gateDecision, lowConfidenceGate) { if (lowConfidenceGate) return "gate_fallback_normal"; if (gateDecision?.forced) return "forced_main_llm"; if (signals.unlimited) return "admin_unlimited_request"; if (signals.codex) return "codex_expanded"; if (signals.feedbackExport) return "feedback_export_expanded"; if (signals.debug) return "debug_expanded"; if (signals.routeOrApi) return "route_docs_okf"; if (signals.lumiInternal) return "lumi_internal_okf"; if (signals.knowledgeLookup) return "simple_knowledge_okf"; if (signals.support) return "support_okf"; if (signals.casual) return "casual_fast"; return "default_normal"; } function modeFromRequestClass(requestClass) { if (requestClass === "navigation_help" || requestClass === "simple_answer") return "fast"; if (requestClass === "admin_debug" || requestClass === "explicit_long") return "expanded"; return "normal"; } function sourceKey(originContext) { const source = String(originContext?.origin || originContext?.platform || "webui").toLowerCase(); return SOURCE_DEFAULTS[source] ? source : "other"; } function clampBudget(value) { return Math.max(64, Math.min(32768, Math.round(Number(value) || 512))); } function clampChars(value, fallback) { const number = Number(value); return Math.max(100, Math.min(12000, Math.round(Number.isFinite(number) ? number : fallback))); } function isSimpleKnowledgeLookup(message) { const text = String(message || "").trim(); if (!text || text.length > 180 || text.split(/\s+/).length > 18) return false; if (/\b(who|what)\s+(?:are|r)\s+you\b|\byour\s+(?:name|identity)\b/i.test(text)) return false; return ( /^(?:who|what)\s+(?:is|are|was|were)\s+["'`]?[\p{L}\p{N}_ .'-]{2,80}["'`]?\??$/iu.test(text) || /^(?:tell me about|describe|identify)\s+["'`]?[\p{L}\p{N}_ .'-]{2,80}["'`]?\??$/iu.test(text) ); } module.exports = { MODE_BUDGETS, SOURCE_DEFAULTS, buildControllerDecision, buildSourceProfile, isSimpleKnowledgeLookup, normalizeControllerDecision, okfLimitForController, outputBudgetForController };