//#region src/mcp/instrument-file.ts
const PROVIDER_IMPORT_MAP = {
	openai: {
		module: "openai",
		defaultExport: "OpenAI",
		namedExport: "openai"
	},
	"@anthropic-ai/sdk": {
		module: "@anthropic-ai/sdk",
		defaultExport: "Anthropic",
		namedExport: "anthropic"
	},
	"@google/generative-ai": {
		module: "@google/generative-ai",
		defaultExport: "GoogleGenerativeAI",
		namedExport: "gemini"
	},
	"@google/genai": {
		module: "@google/genai",
		defaultExport: "GoogleGenAI",
		namedExport: "genai"
	},
	"@mistralai/mistralai": {
		module: "@mistralai/mistralai",
		defaultExport: "Mistral",
		namedExport: "mistral"
	},
	"@azure/openai": {
		module: "@azure/openai",
		defaultExport: "AzureOpenAI",
		namedExport: "azureOpenai"
	},
	"cohere-ai": {
		module: "cohere-ai",
		defaultExport: "CohereClient",
		namedExport: "cohere"
	}
};
function matchConstructor(source, constructorName) {
	const results = [];
	const re = new RegExp(`new\\s+${constructorName}\\s*\\(`, "g");
	for (const m of source.matchAll(re)) {
		const openIdx = (m.index ?? 0) + m[0].length - 1;
		let depth = 1;
		let i = openIdx + 1;
		while (i < source.length && depth > 0) {
			if (source[i] === "(") depth++;
			else if (source[i] === ")") depth--;
			i++;
		}
		results.push({
			start: m.index ?? 0,
			end: i,
			fullMatch: source.slice(m.index ?? 0, i)
		});
	}
	return results;
}
const ROUTE_HANDLER_RE = /export\s+async\s+function\s+(?:POST|GET|PUT|DELETE)\b/;
const EXPRESS_HANDLER_RE = /(?:app|router)\.\s*(?:get|post|put|delete)\s*\(\s*['"][^'"]+['"]\s*,\s*(?:async\s+)?\(/;
const HONO_HANDLER_RE = /(?:app|router)\.\s*(?:get|post|put|delete)\s*\(\s*['"][^'"]+['"]\s*,\s*(?:async\s+)?\(\s*c\b/;
function replaceProviderImports(source, providers, bootstrapImportPath) {
	let result = source;
	const namedImports = [];
	for (const provider of providers) {
		const mapping = PROVIDER_IMPORT_MAP[provider];
		if (!mapping) continue;
		const defaultImportRe = /* @__PURE__ */ new RegExp(`import\\s+${mapping.defaultExport}\\s+from\\s+['"]${mapping.module}['"];?`);
		const escapedModule = mapping.module.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
		const namedImportRe = new RegExp(`import\\s*\\{[^}]*\\b${mapping.defaultExport}\\b[^}]*\\}\\s*from\\s+['"]${escapedModule}['"];?`, "s");
		if (defaultImportRe.test(result)) {
			result = result.replace(defaultImportRe, "");
			namedImports.push(mapping.namedExport);
		} else if (namedImportRe.test(result)) {
			result = result.replace(namedImportRe, "");
			namedImports.push(mapping.namedExport);
		}
		const matches = matchConstructor(result, mapping.defaultExport);
		for (let i = matches.length - 1; i >= 0; i--) {
			const match = matches[i];
			if (match) result = result.slice(0, match.start) + mapping.namedExport + result.slice(match.end);
		}
	}
	if (namedImports.length > 0) result = `import { ${namedImports.join(", ")} } from '${bootstrapImportPath}';\n` + result;
	return result;
}
function addSessionWrapping(source, agentId, bootstrapImportPath) {
	let result = source;
	const existingImportMatch = (/* @__PURE__ */ new RegExp(`import\\s*\\{([^}]*)\\}\\s*from\\s*['"]${bootstrapImportPath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}['"]`)).exec(result);
	if (existingImportMatch) {
		const existingNames = existingImportMatch[1] ?? "";
		if (!existingNames.split(",").map((s) => s.trim()).includes("ai")) {
			const newNames = existingNames.trim() ? `ai, ${existingNames.trim()}` : "ai";
			result = result.replace(existingImportMatch[0], `import { ${newNames} } from '${bootstrapImportPath}'`);
		}
	} else if (!result.includes(`from '${bootstrapImportPath}'`) && !result.includes(`from "${bootstrapImportPath}"`)) result = `import { ai } from '${bootstrapImportPath}';\n${result}`;
	const agentLine = `const agent = ai.agent('${agentId}');\n`;
	if (ROUTE_HANDLER_RE.test(result)) {
		const handlerMatch = result.match(/export\s+async\s+function\s+(?:POST|GET|PUT|DELETE)\s*\([^)]*\)\s*\{/);
		result = result.replace(/(export\s+async\s+function\s+(?:POST|GET|PUT|DELETE)\s*\([^)]*\)\s*\{)/, `$1\n  ${agentLine.trim()}\n  const { messages, userId, sessionId } = await req.json();\n  // TODO(required): Ensure userId comes from auth, not the request body, to prevent spoofing.\n  // sessionId is optional — omit it and the SDK auto-generates a unique UUID per request.\n  const _response = await agent.session({ userId, ...(sessionId && { sessionId }) }).run(async (s) => {`);
		if (handlerMatch?.index != null) {
			const openBraceIdx = result.indexOf("{", handlerMatch.index);
			if (openBraceIdx >= 0) {
				let depth = 1;
				let i = openBraceIdx + 1;
				while (i < result.length && depth > 0) {
					if (result[i] === "{") depth++;
					else if (result[i] === "}") depth--;
					i++;
				}
				const closingBraceIdx = i - 1;
				result = `${result.slice(0, closingBraceIdx)}  });\n  await ai.flush();\n  return _response;\n${result.slice(closingBraceIdx)}`;
			}
		}
	} else if (EXPRESS_HANDLER_RE.test(result) || HONO_HANDLER_RE.test(result)) result = result.replace(/((?:app|router)\.\s*(?:get|post|put|delete)\s*\(\s*['"][^'"]+['"]\s*,\s*(?:async\s+)?\([^)]*\)\s*(?:=>)?\s*\{)/, `$1\n    // TODO(required): Replace with the real user ID from your auth/request context.\n    // Without a real userId, per-user funnels, retention, and cohorts won't work.\n    const _userId = 'anonymous'; // e.g. req.user.id, req.auth.sub, req.session.userId\n    ${agentLine.trim()}\n    const _response = await agent.session({ userId: _userId }).run(async (s) => {`);
	return result;
}
function addUserMessageTracking(source) {
	const match = /(const\s+\{[^}]*\}\s*=\s*(?:await\s+)?(?:req\.body|request\.json\(\)|await\s+request\.json\(\)))/.exec(source);
	if (match) return source.replace(match[0], `${match[0]};\n    // TODO: extract user message and call s.trackUserMessage(userMessage)`);
	return source;
}
function instrumentFile(opts) {
	if (opts.tier === "quick_start") return opts.source;
	let result = opts.source;
	result = replaceProviderImports(result, opts.providers, opts.bootstrapImportPath);
	if (opts.tier === "advanced") {
		result = addSessionWrapping(result, opts.agentId, opts.bootstrapImportPath);
		result = addUserMessageTracking(result);
	}
	return result;
}

//#endregion
export { instrumentFile };
//# sourceMappingURL=instrument-file.js.map