{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/core/web-research/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAoB,MAAM,YAAY,CAAC;AA6DtE,wBAAgB,qBAAqB,CAAC,WAAW,GAAE,MAAM,CAAC,UAAwB,GAAG,iBAAiB,CA0CrG","sourcesContent":["import { type WebResearchConfig, WebResearchError } from \"./types.js\";\n\nconst DEFAULT_SEARXNG_URL = \"http://127.0.0.1:18888\";\n\nfunction integerEnvironment(\n\tenvironment: NodeJS.ProcessEnv,\n\tname: string,\n\tfallback: number,\n\tminimum: number,\n\tmaximum: number,\n): number {\n\tconst raw = environment[name];\n\tif (raw === undefined || raw === \"\") return fallback;\n\tconst value = Number(raw);\n\tif (!Number.isSafeInteger(value) || value < minimum || value > maximum) {\n\t\tthrow new WebResearchError(\n\t\t\t\"INVALID_CONFIGURATION\",\n\t\t\t`${name} must be an integer between ${minimum} and ${maximum}`,\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction booleanEnvironment(environment: NodeJS.ProcessEnv, name: string, fallback: boolean): boolean {\n\tconst raw = environment[name];\n\tif (raw === undefined || raw === \"\") return fallback;\n\tif (raw === \"1\" || raw === \"true\") return true;\n\tif (raw === \"0\" || raw === \"false\") return false;\n\tthrow new WebResearchError(\"INVALID_CONFIGURATION\", `${name} must be true, false, 1, or 0`);\n}\n\nfunction searchProvider(environment: NodeJS.ProcessEnv): WebResearchConfig[\"primarySearchProvider\"] {\n\tconst value = environment.JENSEN_WEB_SEARCH_PROVIDER ?? \"auto\";\n\tif (value === \"auto\" || value === \"searxng\" || value === \"duckduckgo-lite\") return value;\n\tthrow new WebResearchError(\n\t\t\"INVALID_CONFIGURATION\",\n\t\t\"JENSEN_WEB_SEARCH_PROVIDER must be auto, searxng, or duckduckgo-lite\",\n\t);\n}\n\nfunction searxngUrl(environment: NodeJS.ProcessEnv): string {\n\tconst value = environment.JENSEN_SEARXNG_URL ?? DEFAULT_SEARXNG_URL;\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(value);\n\t} catch (error) {\n\t\tthrow new WebResearchError(\"INVALID_CONFIGURATION\", \"JENSEN_SEARXNG_URL must be an absolute HTTP URL\", {\n\t\t\tcause: error,\n\t\t});\n\t}\n\tif ((parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") || parsed.username || parsed.password) {\n\t\tthrow new WebResearchError(\n\t\t\t\"INVALID_CONFIGURATION\",\n\t\t\t\"JENSEN_SEARXNG_URL must be HTTP(S) and must not contain credentials\",\n\t\t);\n\t}\n\tparsed.hash = \"\";\n\tparsed.search = \"\";\n\treturn parsed.toString().replace(/\\/$/, \"\");\n}\n\nexport function loadWebResearchConfig(environment: NodeJS.ProcessEnv = process.env): WebResearchConfig {\n\treturn {\n\t\tprimarySearchProvider: searchProvider(environment),\n\t\tsearxngUrl: searxngUrl(environment),\n\t\tsearchTimeoutMs: integerEnvironment(environment, \"JENSEN_WEB_SEARCH_TIMEOUT_MS\", 10_000, 250, 120_000),\n\t\tfetchTimeoutMs: integerEnvironment(environment, \"JENSEN_WEB_FETCH_TIMEOUT_MS\", 20_000, 500, 180_000),\n\t\tmaxResponseBytes: integerEnvironment(\n\t\t\tenvironment,\n\t\t\t\"JENSEN_WEB_FETCH_MAX_BYTES\",\n\t\t\t5 * 1024 * 1024,\n\t\t\t1024,\n\t\t\t50 * 1024 * 1024,\n\t\t),\n\t\tmaxDecompressedBytes: integerEnvironment(\n\t\t\tenvironment,\n\t\t\t\"JENSEN_WEB_FETCH_MAX_DECOMPRESSED_BYTES\",\n\t\t\t10 * 1024 * 1024,\n\t\t\t1024,\n\t\t\t100 * 1024 * 1024,\n\t\t),\n\t\tmaxRedirects: integerEnvironment(environment, \"JENSEN_WEB_FETCH_MAX_REDIRECTS\", 5, 0, 10),\n\t\tmaxSearchResults: integerEnvironment(environment, \"JENSEN_WEB_SEARCH_MAX_RESULTS\", 10, 1, 50),\n\t\tsafeSearch: booleanEnvironment(environment, \"JENSEN_WEB_SAFE_SEARCH\", true),\n\t\tuserAgent:\n\t\t\tenvironment.JENSEN_WEB_USER_AGENT?.trim() ||\n\t\t\t\"Jensen-Code-Web-Research/1.0 (+https://github.com/apholdings/jensen-code)\",\n\t\tbrowserExecutablePath: environment.JENSEN_PLAYWRIGHT_EXECUTABLE_PATH?.trim() || undefined,\n\t\tresearch: {\n\t\t\tmaxQueries: integerEnvironment(environment, \"JENSEN_RESEARCH_MAX_QUERIES\", 4, 1, 12),\n\t\t\tmaxSources: integerEnvironment(environment, \"JENSEN_RESEARCH_MAX_SOURCES\", 6, 1, 20),\n\t\t\tmaxBytes: integerEnvironment(\n\t\t\t\tenvironment,\n\t\t\t\t\"JENSEN_RESEARCH_MAX_BYTES\",\n\t\t\t\t20 * 1024 * 1024,\n\t\t\t\t1024,\n\t\t\t\t100 * 1024 * 1024,\n\t\t\t),\n\t\t\tmaxBrowserRenders: integerEnvironment(environment, \"JENSEN_RESEARCH_MAX_BROWSER_RENDERS\", 1, 0, 4),\n\t\t\tmaxElapsedMs: integerEnvironment(environment, \"JENSEN_RESEARCH_MAX_ELAPSED_MS\", 120_000, 1000, 600_000),\n\t\t\tmaxParallelFetches: integerEnvironment(environment, \"JENSEN_RESEARCH_MAX_PARALLEL_FETCHES\", 3, 1, 8),\n\t\t},\n\t};\n}\n"]}