import path from "path"; export const BACKEND_ROOT = path.resolve(__dirname, ".."); export const MODULE_ROOT = path.resolve(BACKEND_ROOT, ".."); export const PROJECT_ROOT = path.resolve(MODULE_ROOT, ".."); function toBooleanFlag(value: string | undefined, defaultValue: boolean): boolean { if (!value || value.trim() === "") { return defaultValue; } const lowered = value.trim().toLowerCase(); return !(lowered === "0" || lowered === "false" || lowered === "off" || lowered === "no"); } function toNumberFlag(value: string | undefined, defaultValue: number): number { if (!value || value.trim() === "") { return defaultValue; } const parsed = Number(value); return Number.isFinite(parsed) ? parsed : defaultValue; } function toStringListFlag(value: string | undefined, defaultValue: string[]): string[] { const source = String(value ?? "").trim(); if (!source) { return [...defaultValue]; } const tokens = source .split(/[,\s;]+/g) .map((item) => item.trim()) .filter((item) => item.length > 0); return tokens.length > 0 ? Array.from(new Set(tokens)) : [...defaultValue]; } export const PORT = Number(process.env.PORT ?? 8787); export const TIMEZONE = process.env.TZ_FALLBACK ?? "Europe/Moscow"; export const DEFAULT_OPENAI_BASE_URL = process.env.OPENAI_BASE_URL ?? "https://api.openai.com/v1"; export const DEFAULT_MODEL = process.env.OPENAI_MODEL ?? "gpt-4o-mini"; export const DEFAULT_TEMPERATURE = Number(process.env.OPENAI_TEMPERATURE ?? 0); export const DEFAULT_MAX_OUTPUT_TOKENS = Number(process.env.OPENAI_MAX_OUTPUT_TOKENS ?? 700); export const DEFAULT_PROMPT_VERSION = process.env.DEFAULT_PROMPT_VERSION ?? "normalizer_v2_0_2"; export const FEATURE_ASSISTANT_INVESTIGATION_STATE_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1, true ); export const FEATURE_ASSISTANT_CONTRACTS_V11 = toBooleanFlag(process.env.FEATURE_ASSISTANT_CONTRACTS_V11, true); export const FEATURE_ASSISTANT_STATE_FOLLOWUP_BINDING_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_STATE_FOLLOWUP_BINDING_V1, true ); export const FEATURE_ASSISTANT_EVIDENCE_ENRICHMENT_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_EVIDENCE_ENRICHMENT_V1, true ); export const FEATURE_ASSISTANT_BROAD_GUARD_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_BROAD_GUARD_V1, true ); export const FEATURE_ASSISTANT_MIN_EVIDENCE_GATE_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_MIN_EVIDENCE_GATE_V1, true ); export const FEATURE_ASSISTANT_ANTI_GENERIC_RANKING_GUARD_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ANTI_GENERIC_RANKING_GUARD_V1, true ); export const FEATURE_ASSISTANT_ANSWER_POLICY_V11 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ANSWER_POLICY_V11, true ); export const FEATURE_ASSISTANT_ACCOUNTANT_EVAL_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ACCOUNTANT_EVAL_V1, true ); export const FEATURE_ASSISTANT_PROBLEM_UNITS_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_PROBLEM_UNITS_V1, true ); export const FEATURE_ASSISTANT_PROBLEM_CENTRIC_ANSWER_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_PROBLEM_CENTRIC_ANSWER_V1, true ); export const FEATURE_ASSISTANT_PROBLEM_UNIT_CONTINUITY_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_PROBLEM_UNIT_CONTINUITY_V1, true ); export const FEATURE_ASSISTANT_STAGE2_EVAL_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_STAGE2_EVAL_V1, false ); export const FEATURE_ASSISTANT_LIFECYCLE_RUNTIME_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_LIFECYCLE_RUNTIME_V1, true ); export const FEATURE_ASSISTANT_LIFECYCLE_ANSWER_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_LIFECYCLE_ANSWER_V1, true ); export const FEATURE_ASSISTANT_GRAPH_RUNTIME_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_GRAPH_RUNTIME_V1, true ); export const FEATURE_ASSISTANT_MCP_RUNTIME_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_MCP_RUNTIME_V1, false ); export const FEATURE_ASSISTANT_ADDRESS_QUERY_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ADDRESS_QUERY_V1, true ); export const FEATURE_ASSISTANT_ADDRESS_QUERY_LLM_PREDECOMPOSE_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ADDRESS_QUERY_LLM_PREDECOMPOSE_V1, true ); export const FEATURE_ASSISTANT_ADDRESS_QUERY_LIVE_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ADDRESS_QUERY_LIVE_V1, true ); export const FEATURE_ASSISTANT_ADDRESS_NAVIGATION_STATE_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ADDRESS_NAVIGATION_STATE_V1, true ); export const FEATURE_ASSISTANT_CAPABILITY_ROUTE_GUARD_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_CAPABILITY_ROUTE_GUARD_V1, true ); export const FEATURE_ASSISTANT_ROUTE_ADDRESS_GENERIC_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ROUTE_ADDRESS_GENERIC_V1, true ); export const FEATURE_ASSISTANT_ROUTE_DRILLDOWN_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ROUTE_DRILLDOWN_V1, true ); export const FEATURE_ASSISTANT_ROUTE_BALANCE_EXACT_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ROUTE_BALANCE_EXACT_V1, true ); export const FEATURE_ASSISTANT_ROUTE_PAYABLES_CONFIRMED_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ROUTE_PAYABLES_CONFIRMED_V1, true ); export const FEATURE_ASSISTANT_ROUTE_RECEIVABLES_CONFIRMED_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ROUTE_RECEIVABLES_CONFIRMED_V1, true ); export const FEATURE_ASSISTANT_ROUTE_PAYABLES_HEURISTIC_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ROUTE_PAYABLES_HEURISTIC_V1, true ); export const FEATURE_ASSISTANT_ROUTE_RECEIVABLES_HEURISTIC_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ROUTE_RECEIVABLES_HEURISTIC_V1, true ); export const FEATURE_ASSISTANT_ROUTE_SHADOW_PAYABLES_EXACT_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ROUTE_SHADOW_PAYABLES_EXACT_V1, false ); export const FEATURE_ASSISTANT_ROUTE_EXPECTATION_AUDIT_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ROUTE_EXPECTATION_AUDIT_V1, true ); export const FEATURE_ASSISTANT_ROUTE_EXPECTATION_HARD_GUARD_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_ROUTE_EXPECTATION_HARD_GUARD_V1, false ); export const FEATURE_ASSISTANT_LIVING_CHAT_ROUTER_V1 = toBooleanFlag( process.env.FEATURE_ASSISTANT_LIVING_CHAT_ROUTER_V1, true ); export const ASSISTANT_MCP_PROXY_URL = (process.env.ASSISTANT_MCP_PROXY_URL ?? "http://127.0.0.1:6003").replace( /\/+$/, "" ); export const ASSISTANT_MCP_CHANNEL = process.env.ASSISTANT_MCP_CHANNEL ?? "default"; export const ASSISTANT_MCP_TIMEOUT_MS = toNumberFlag(process.env.ASSISTANT_MCP_TIMEOUT_MS, 6000); export const ASSISTANT_MCP_LIVE_LIMIT = Math.max(1, Math.trunc(toNumberFlag(process.env.ASSISTANT_MCP_LIVE_LIMIT, 24))); export const VAT_PAYABLE_68_PREFIXES = toStringListFlag(process.env.VAT_PAYABLE_68_PREFIXES, ["68.02"]); export const VAT_PAYABLE_19_PREFIXES = toStringListFlag(process.env.VAT_PAYABLE_19_PREFIXES, ["19"]); export const DATA_DIR = process.env.DATA_DIR ?? path.resolve(MODULE_ROOT, "data"); export const TRACES_DIR = path.resolve(DATA_DIR, "traces"); export const PRESETS_DIR = path.resolve(DATA_DIR, "presets"); export const EVAL_CASES_DIR = path.resolve(DATA_DIR, "eval_cases"); export const ASSISTANT_SESSIONS_DIR = path.resolve(DATA_DIR, "assistant_sessions"); export const ASSISTANT_ANNOTATIONS_DIR = path.resolve(DATA_DIR, "assistant_annotations"); export const ASSISTANT_ANNOTATIONS_FILE = path.resolve(ASSISTANT_ANNOTATIONS_DIR, "annotations.json"); export const AUTORUN_ANNOTATIONS_DIR = path.resolve(DATA_DIR, "autorun_annotations"); export const AUTORUN_ANNOTATIONS_FILE = path.resolve(AUTORUN_ANNOTATIONS_DIR, "annotations.json"); export const AUTORUN_GENERATOR_DIR = path.resolve(DATA_DIR, "autorun_generators"); export const AUTORUN_GENERATOR_HISTORY_FILE = path.resolve(AUTORUN_GENERATOR_DIR, "history.json"); export const SHARED_LLM_CONNECTION_FILE = path.resolve(DATA_DIR, "shared_llm_connection.json"); export const PROMPTS_DIR = path.resolve(MODULE_ROOT, "prompts"); export const REPORTS_DIR = path.resolve(MODULE_ROOT, "reports"); export const ARTIFACTS_DIR = path.resolve(PROJECT_ROOT, "artifacts"); export const EVAL_DATASETS_DIR = path.resolve(MODULE_ROOT, "eval_cases"); export const SCHEMAS_DIR = path.resolve(BACKEND_ROOT, "src", "schemas"); export const ARCH_EXPORT_2020_DIR = path.resolve(MODULE_ROOT, "..", "docs", "ARCH", "2020экспорт"); export const ASSISTANT_CANON_FILE = path.resolve(MODULE_ROOT, "..", "docs", "TECH", "assistant_canon.md"); export const ASSISTANT_CAPABILITIES_REGISTRY_FILE = path.resolve( MODULE_ROOT, "..", "docs", "TECH", "capabilities_registry.json" ); export const MANUAL_CASE_DECISION_SCHEMA_FILE = path.resolve( MODULE_ROOT, "..", "docs", "TECH", "manual_case_decision_schema.json" );