export declare const buildDocsIndexScriptTemplate = "/**\n * Precompute document embeddings at build time.\n *\n * Runs before `next build` (wired into the \"build\" script in package.json).\n * Embeds every docs chunk once and writes services/mcp/docs-index.json, so the\n * running app loads vectors instead of re-embedding the whole doc set on every\n * serverless cold start (the main cause of slow first chats / proxy timeouts).\n *\n * Fails soft: without an API key, or on any embedding error, it leaves the\n * existing (possibly empty) index in place and exits 0 so the build proceeds.\n * The app then falls back to embedding on demand at runtime.\n */\nimport path from \"node:path\";\nimport { writeFileSync } from \"node:fs\";\n// @next/env is CommonJS; use a default import so the named export resolves\n// under tsx's ESM loader (a named import is not statically detected).\nimport nextEnv from \"@next/env\";\nimport { getAllDocsChunks } from \"../services/mcp/tools\";\nimport { getLLMConfig, isLLMAvailable } from \"../services/llm/config\";\nimport { createEmbeddings } from \"../services/llm/factory\";\nimport { reduceDims, quantizeInt8, encodeInt8 } from \"../services/mcp/vector\";\n\n// This runs as a standalone process before `next build`, so it must load\n// .env / .env.local / .env.production itself (the same way Next does). Real\n// environment variables still take precedence over .env files.\nnextEnv.loadEnvConfig(process.cwd());\n\nconst OUTPUT = path.join(process.cwd(), \"services\", \"mcp\", \"docs-index.json\");\nconst BATCH_SIZE = 10;\n\nasync function main() {\n if (!isLLMAvailable()) {\n console.warn(\n \"[doccupine] No LLM API key set - skipping embedding precompute. \" +\n \"The chat will embed docs on demand at runtime.\",\n );\n return;\n }\n\n const chunks = await getAllDocsChunks();\n if (chunks.length === 0) {\n console.warn(\"[doccupine] No docs found to embed - skipping precompute.\");\n return;\n }\n\n const config = getLLMConfig();\n const embeddings = createEmbeddings(config);\n\n // Embed in small batches to stay within provider token limits, then reduce\n // each vector to config.embeddingDims and quantize to int8. Storing raw float\n // arrays as JSON balloons to 100MB+ on large doc sets, which OOMs / stalls the\n // serverless chat on cold start; int8 base64 keeps the index ~20x smaller.\n const texts = chunks.map((c) => c.text);\n const encoded: string[] = [];\n for (let i = 0; i < texts.length; i += BATCH_SIZE) {\n const batch = await embeddings.embedDocuments(\n texts.slice(i, i + BATCH_SIZE),\n );\n for (const vector of batch) {\n encoded.push(\n encodeInt8(quantizeInt8(reduceDims(vector, config.embeddingDims))),\n );\n }\n }\n\n const data = {\n provider: config.provider,\n embeddingModel: config.embeddingModel,\n dims: config.embeddingDims,\n quantization: \"int8\",\n chunks: chunks.map((c, i) => ({ ...c, embedding: encoded[i] })),\n };\n\n writeFileSync(OUTPUT, JSON.stringify(data));\n // eslint-disable-next-line no-console -- build-time progress belongs in CI logs\n console.log(\n `[doccupine] Precomputed ${data.chunks.length} doc embeddings -> ${OUTPUT}`,\n );\n}\n\nmain()\n .then(() => process.exit(0))\n .catch((error) => {\n // Never fail the build on an embedding error - fall back to runtime embedding.\n console.warn(\n \"[doccupine] Embedding precompute failed; continuing build. \" +\n \"The chat will embed docs at runtime.\",\n error instanceof Error ? error.message : error,\n );\n process.exit(0);\n });\n";