const require_rolldown_runtime = require("./rolldown-runtime-D_mwlA32.cjs");
const require_logger = require("./logger-DuG3amVa.cjs");
const require_fetch = require("./fetch-Hdu2Q-w3.cjs");
const require_util = require("./util-M3cOWPu3.cjs");
const require_cache = require("./cache-JYoIjHBA.cjs");
const require_util$1 = require("./util-DtSnbKEe.cjs");
const require_util$2 = require("./util-BYWxXWQj.cjs");
const require_base = require("./base-Drq4pKbj.cjs");
let crypto = require("crypto");
//#region src/providers/google/vertex.ts
var vertex_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
	VertexChatProvider: () => VertexChatProvider,
	VertexEmbeddingProvider: () => VertexEmbeddingProvider,
	getGoogleVertexEmbeddingProvider: () => getGoogleVertexEmbeddingProvider,
	getGoogleVertexProviders: () => getGoogleVertexProviders
});
function getVertexApiHost(region, configApiHost, envOverrides) {
	return configApiHost || envOverrides?.VERTEX_API_HOST || require_logger.getEnvString("VERTEX_API_HOST") || (region === "global" ? "aiplatform.googleapis.com" : `${region}-aiplatform.googleapis.com`);
}
function getVertexBodyCacheKey(prefix, body, apiHost) {
	const serialized = typeof body === "string" ? body : JSON.stringify(body);
	return `${prefix}:${(0, crypto.createHmac)("sha256", "promptfoo:vertex:cache-key:v1").update(apiHost).update("\0").update(serialized ?? String(body)).digest("hex")}`;
}
/**
* Vertex AI provider for Gemini, Claude, Llama, and Palm2 models.
*
* Extends GoogleGenericProvider for shared functionality like MCP integration,
* authentication management, and resource cleanup.
*/
var VertexChatProvider = class extends require_base.GoogleGenericProvider {
	constructor(modelName, options = {}) {
		super(modelName, {
			...options,
			config: {
				...options.config,
				vertexai: true
			}
		});
	}
	/**
	* Get the Vertex AI API host based on region.
	* Public for use by integrations like Adaline Gateway.
	*/
	getApiHost() {
		const region = this.getRegion();
		return this.config.apiHost || this.env?.VERTEX_API_HOST || require_logger.getEnvString("VERTEX_API_HOST") || (region === "global" ? "aiplatform.googleapis.com" : `${region}-aiplatform.googleapis.com`);
	}
	/**
	* Get the API version for Vertex AI.
	*/
	getApiVersion() {
		return this.config.apiVersion || this.env?.VERTEX_API_VERSION || require_logger.getEnvString("VERTEX_API_VERSION") || "v1";
	}
	/**
	* Get the publisher for the model.
	*/
	getPublisher() {
		return this.config.publisher || this.env?.VERTEX_PUBLISHER || require_logger.getEnvString("VERTEX_PUBLISHER") || "google";
	}
	/**
	* Get the API endpoint URL for Vertex AI.
	* Note: For Gemini, the actual endpoint is constructed dynamically based on mode.
	*/
	getApiEndpoint(action) {
		const actionSuffix = action ? `:${action}` : "";
		return `https://${this.getApiHost()}/${this.getApiVersion()}/publishers/${this.getPublisher()}/models/${this.modelName}${actionSuffix}`;
	}
	/**
	* Get authentication headers for Vertex AI.
	* For OAuth mode, this returns minimal headers; the client handles auth.
	* For express mode, the API key is passed via x-goog-api-key header for improved security.
	*/
	async getAuthHeaders() {
		const headers = {
			"Content-Type": "application/json",
			...this.config.headers
		};
		if (this.isExpressMode()) {
			const apiKey = this.getApiKey();
			if (apiKey) headers["x-goog-api-key"] = apiKey;
		}
		return headers;
	}
	/**
	* Helper method to get Google client with credentials support.
	* Public for use by integrations like Adaline Gateway.
	*/
	async getClientWithCredentials() {
		const { client } = await require_util$1.getGoogleClient({
			credentials: require_util$1.loadCredentials(this.config.credentials),
			googleAuthOptions: this.config.googleAuthOptions,
			scopes: this.config.scopes,
			keyFilename: this.config.keyFilename
		});
		return client;
	}
	async callApi(prompt, context) {
		const spanContext = {
			system: this.modelName.includes("claude") ? "vertex:anthropic" : this.modelName.includes("gemini") ? "vertex:gemini" : this.modelName.includes("llama") ? "vertex:llama" : "vertex:palm2",
			operationName: "chat",
			model: this.modelName,
			providerId: this.id(),
			temperature: this.config.temperature,
			topP: this.config.topP,
			maxTokens: this.config.maxOutputTokens || this.config.max_tokens,
			testIndex: context?.test?.vars?.__testIdx,
			promptLabel: context?.prompt?.label,
			traceparent: context?.traceparent
		};
		const resultExtractor = (response) => {
			const result = {};
			if (response.tokenUsage) result.tokenUsage = {
				prompt: response.tokenUsage.prompt,
				completion: response.tokenUsage.completion,
				total: response.tokenUsage.total
			};
			return result;
		};
		return require_util.withGenAISpan(spanContext, () => this.callApiInternal(prompt, context), resultExtractor);
	}
	async callApiInternal(prompt, context) {
		if (this.modelName.includes("claude")) return this.callClaudeApi(prompt, context);
		else if (this.modelName.includes("gemini")) return this.callGeminiApi(prompt, context);
		else if (this.modelName.includes("llama")) return this.callLlamaApi(prompt, context);
		return this.callPalm2Api(prompt);
	}
	async callClaudeApi(prompt, context) {
		let normalizedPrompt = prompt;
		if (prompt.trim().startsWith("- role:")) try {
			const parsed = (await import("js-yaml")).default.load(prompt);
			normalizedPrompt = JSON.stringify(parsed);
		} catch (err) {
			return { error: `Chat Completion prompt is not a valid YAML string: ${err}` };
		}
		const { system, extractedMessages, thinking } = require_util$2.parseMessages(normalizedPrompt);
		let mergedSystem = system;
		const parsedConfigInstruction = require_util$1.parseConfigSystemInstruction(this.config.systemInstruction, context?.vars);
		if (parsedConfigInstruction) {
			const configSystemBlocks = [];
			for (const part of parsedConfigInstruction.parts) if (part.text) configSystemBlocks.push({
				type: "text",
				text: part.text
			});
			if (configSystemBlocks.length > 0) mergedSystem = [...configSystemBlocks, ...mergedSystem || []];
		}
		const samplingParamsDeprecated = require_util$2.isSamplingParamsDeprecatedClaudeModel(this.modelName);
		const requestedThinkingConfig = this.config.thinking || thinking;
		const thinkingConfig = samplingParamsDeprecated && requestedThinkingConfig?.type === "enabled" ? { type: "adaptive" } : requestedThinkingConfig;
		const isThinkingEnabled = thinkingConfig?.type === "enabled" || thinkingConfig?.type === "adaptive";
		let maxTokens = this.config.max_tokens || this.config.maxOutputTokens || 0;
		if (!maxTokens) maxTokens = isThinkingEnabled ? 2048 : 512;
		if (thinkingConfig?.type === "enabled" && thinkingConfig.budget_tokens && maxTokens < thinkingConfig.budget_tokens) maxTokens = thinkingConfig.budget_tokens + 1024;
		const resolvedTemperature = samplingParamsDeprecated ? void 0 : this.config.temperature;
		const resolvedTopP = samplingParamsDeprecated ? void 0 : this.config.top_p || this.config.topP;
		const resolvedTopK = samplingParamsDeprecated ? void 0 : this.config.top_k || this.config.topK;
		const body = {
			anthropic_version: this.config.anthropicVersion || this.config.anthropic_version || "vertex-2023-10-16",
			stream: false,
			max_tokens: maxTokens,
			temperature: resolvedTemperature,
			top_p: resolvedTopP,
			top_k: resolvedTopK,
			...mergedSystem ? { system: mergedSystem } : {},
			...thinkingConfig ? { thinking: thinkingConfig } : {},
			messages: extractedMessages
		};
		const showThinking = this.config.showThinking ?? isThinkingEnabled;
		const cache = await require_cache.getCache();
		const apiHost = this.getApiHost();
		const cacheKey = getVertexBodyCacheKey(`vertex:claude:${this.modelName}:showThinking=${showThinking}`, body, apiHost);
		let cachedResponse;
		if (require_cache.isCacheEnabled()) {
			cachedResponse = await cache.get(cacheKey);
			if (cachedResponse) {
				const parsedCachedResponse = JSON.parse(cachedResponse);
				const tokenUsage = parsedCachedResponse.tokenUsage;
				if (tokenUsage) tokenUsage.cached = tokenUsage.total;
				require_logger.logger.debug("Returning cached Vertex Claude response", {
					model: this.modelName,
					cacheKey
				});
				return {
					...parsedCachedResponse,
					cached: true
				};
			}
		}
		let data;
		try {
			const client = await this.getClientWithCredentials();
			const url = `https://${apiHost}/v1/projects/${await this.getProjectId()}/locations/${this.getRegion()}/publishers/anthropic/models/${this.modelName}:rawPredict`;
			data = (await client.request({
				url,
				method: "POST",
				headers: { "Content-Type": "application/json; charset=utf-8" },
				data: body,
				timeout: require_fetch.getRequestTimeoutMs()
			})).data;
		} catch (err) {
			const error = err;
			if (error.response && error.response.data) {
				require_logger.logger.debug(`Claude API error:\n${JSON.stringify(error.response.data)}`);
				return { error: `API call error: ${JSON.stringify(error.response.data)}` };
			}
			require_logger.logger.debug(`Claude API error:\n${JSON.stringify(err)}`);
			return { error: `API call error: ${String(err)}` };
		}
		try {
			const output = require_util$2.outputFromMessage(data, showThinking);
			if (!output) return { error: `No output found in Claude API response: ${JSON.stringify(data)}` };
			const response = {
				cached: false,
				output,
				tokenUsage: {
					...require_util$2.getTokenUsage(data, false),
					numRequests: 1
				},
				cost: require_util$2.calculateAnthropicCost(this.modelName.replace(/-v\d+@/, "-").replace("@", "-"), this.config, data.usage?.input_tokens, data.usage?.output_tokens)
			};
			if (require_cache.isCacheEnabled()) await cache.set(cacheKey, JSON.stringify(response));
			return response;
		} catch (err) {
			return { error: `Claude API response error: ${String(err)}. Response data: ${JSON.stringify(data)}` };
		}
	}
	/**
	* Check if express mode should be used (API key without OAuth).
	* Express mode uses a simplified endpoint format without project/location.
	*
	* Express mode is automatic when an API key is available - users don't need
	* to think about it. Just provide an API key and it works.
	*
	* Express mode is used when:
	* 1. API key is available (VERTEX_API_KEY, GOOGLE_API_KEY, or config.apiKey)
	* 2. User hasn't explicitly disabled it with `expressMode: false`
	* 3. No OAuth/ADC credentials are configured (OAuth takes priority)
	*/
	isExpressMode() {
		const hasApiKey = Boolean(this.getApiKey());
		const explicitlyDisabled = this.config.expressMode === false;
		const hasOAuthConfig = Boolean(this.config.credentials || this.config.keyFilename || this.config.googleAuthOptions?.keyFilename || this.config.googleAuthOptions?.credentials);
		return hasApiKey && !explicitlyDisabled && !hasOAuthConfig;
	}
	async callGeminiApi(prompt, context) {
		if (this.initializationPromise != null) await this.initializationPromise;
		const config = require_util$1.mergeGoogleCompletionOptions(this.config, context?.prompt?.config);
		const { contents, systemInstruction } = require_util$1.geminiFormatAndSystemInstructions(prompt, context?.vars, config.systemInstruction, { useAssistantRole: config.useAssistantRole });
		const { toolConfig, toolsDisabled } = require_util$1.resolveGoogleToolConfig(config);
		const allTools = await this.getAllTools(context, { skipExecutableToolFiles: toolsDisabled });
		const requestTools = toolsDisabled ? require_util$1.removeGoogleFunctionDeclarations(allTools) : allTools;
		const body = {
			contents,
			generationConfig: {
				context: config.context,
				examples: config.examples,
				stopSequences: config.stopSequences,
				temperature: config.temperature,
				maxOutputTokens: config.maxOutputTokens,
				topP: config.topP,
				topK: config.topK,
				...config.generationConfig
			},
			...config.safetySettings ? { safetySettings: require_util$1.normalizeSafetySettings(config.safetySettings) } : {},
			...toolConfig ? { toolConfig } : {},
			...requestTools.length > 0 ? { tools: requestTools } : {},
			...systemInstruction ? { systemInstruction } : {},
			...config.modelArmor && (config.modelArmor.promptTemplate || config.modelArmor.responseTemplate) && { model_armor_config: {
				...config.modelArmor.promptTemplate && { prompt_template_name: config.modelArmor.promptTemplate },
				...config.modelArmor.responseTemplate && { response_template_name: config.modelArmor.responseTemplate }
			} }
		};
		if (config.responseSchema) {
			if (body.generationConfig.response_schema) throw new Error("`responseSchema` provided but `generationConfig.response_schema` already set.");
			let schema = require_util.maybeLoadFromExternalFile(require_util.renderVarsInObject(config.responseSchema, context?.vars));
			if (typeof schema === "string") try {
				schema = JSON.parse(schema);
			} catch (error) {
				throw new Error(`Invalid JSON in responseSchema: ${error}`);
			}
			schema = require_util.renderVarsInObject(schema, context?.vars);
			body.generationConfig.response_schema = schema;
			body.generationConfig.response_mime_type = "application/json";
		}
		const cache = await require_cache.getCache();
		const apiHost = this.getApiHost();
		const cacheKey = getVertexBodyCacheKey(`vertex:${this.modelName}`, body, apiHost);
		let response;
		let cachedResponse;
		if (require_cache.isCacheEnabled()) {
			cachedResponse = await cache.get(cacheKey);
			if (cachedResponse) {
				const parsedCachedResponse = JSON.parse(cachedResponse);
				const tokenUsage = parsedCachedResponse.tokenUsage;
				if (tokenUsage) tokenUsage.cached = tokenUsage.total;
				require_logger.logger.debug("Returning cached Vertex Gemini response", {
					model: this.modelName,
					cacheKey
				});
				response = {
					...parsedCachedResponse,
					cached: true
				};
			}
		}
		if (response === void 0) {
			let data;
			try {
				const endpoint = config.streaming === true ? "streamGenerateContent" : "generateContent";
				if (this.isExpressMode()) {
					const res = await require_fetch.fetchWithProxy(`https://${apiHost}/${this.getApiVersion()}/publishers/${this.getPublisher()}/models/${this.modelName}:${endpoint}`, {
						method: "POST",
						headers: await this.getAuthHeaders(),
						body: JSON.stringify(body),
						signal: AbortSignal.timeout(require_fetch.getRequestTimeoutMs())
					});
					if (!res.ok) {
						const errorData = await res.json().catch(() => null);
						require_logger.logger.debug(`Gemini API express mode error:\n${JSON.stringify(errorData)}`);
						return { error: `API call error: ${res.status} ${res.statusText}${errorData ? `: ${JSON.stringify(errorData)}` : ""}` };
					}
					data = await res.json();
				} else {
					const client = await this.getClientWithCredentials();
					const projectId = await this.getProjectId();
					const url = `https://${apiHost}/${this.getApiVersion()}/projects/${projectId}/locations/${this.getRegion()}/publishers/${this.getPublisher()}/models/${this.modelName}:${endpoint}`;
					data = (await client.request({
						url,
						method: "POST",
						data: body,
						timeout: require_fetch.getRequestTimeoutMs()
					})).data;
				}
			} catch (err) {
				const geminiError = err;
				if (geminiError.response && geminiError.response.data && geminiError.response.data[0] && geminiError.response.data[0].error) {
					const errorDetails = geminiError.response.data[0].error;
					const code = errorDetails.code;
					const message = errorDetails.message;
					const status = errorDetails.status;
					require_logger.logger.error(`Gemini API error:\n${JSON.stringify(errorDetails)}`);
					return { error: `API call error: Status ${status}, Code ${code}, Message:\n\n${message}` };
				}
				require_logger.logger.debug(`Gemini API error:\n${JSON.stringify(err)}`);
				return { error: `API call error: ${String(err)}` };
			}
			try {
				const normalizedData = Array.isArray(data) ? data : [data];
				const error = normalizedData[0]?.error;
				if (error) return { error: `Error ${error.code}: ${error.message}` };
				const dataWithResponse = normalizedData;
				let output;
				for (const datum of dataWithResponse) {
					if (datum.promptFeedback?.blockReason) {
						const isModelArmor = datum.promptFeedback.blockReason === "MODEL_ARMOR";
						const blockReasonMessage = datum.promptFeedback.blockReasonMessage || `Content was blocked due to ${isModelArmor ? "Model Armor" : "safety settings"}: ${datum.promptFeedback.blockReason}`;
						return {
							output: blockReasonMessage,
							tokenUsage: {
								total: datum.usageMetadata?.totalTokenCount || 0,
								prompt: datum.usageMetadata?.promptTokenCount || 0,
								completion: datum.usageMetadata?.candidatesTokenCount || 0
							},
							guardrails: {
								flagged: true,
								flaggedInput: true,
								flaggedOutput: false,
								reason: blockReasonMessage
							},
							metadata: { modelArmor: isModelArmor ? {
								blockReason: datum.promptFeedback.blockReason,
								...datum.promptFeedback.blockReasonMessage && { blockReasonMessage: datum.promptFeedback.blockReasonMessage }
							} : void 0 }
						};
					}
					const candidate = require_util$1.getCandidate(datum);
					if (candidate.finishReason && [
						"SAFETY",
						"PROHIBITED_CONTENT",
						"RECITATION",
						"BLOCKLIST",
						"SPII",
						"IMAGE_SAFETY"
					].includes(candidate.finishReason)) {
						const finishReason = `Content was blocked due to safety settings with finish reason: ${candidate.finishReason}.`;
						const tokenUsage = {
							total: datum.usageMetadata?.totalTokenCount || 0,
							prompt: datum.usageMetadata?.promptTokenCount || 0,
							completion: datum.usageMetadata?.candidatesTokenCount || 0
						};
						const guardrails = {
							flagged: true,
							flaggedInput: false,
							flaggedOutput: true,
							reason: finishReason
						};
						if (require_logger.state.config?.redteam) return {
							output: finishReason,
							tokenUsage,
							guardrails
						};
						return {
							error: finishReason,
							guardrails
						};
					} else if (candidate.finishReason && candidate.finishReason === "MAX_TOKENS") {
						if (candidate.content?.parts) output = require_util$1.mergeParts(output, require_util$1.formatCandidateContents(candidate));
						const outputTokens = datum.usageMetadata?.candidatesTokenCount || 0;
						require_logger.logger.debug(`Gemini API: MAX_TOKENS reached`, {
							finishReason: candidate.finishReason,
							outputTokens,
							totalTokens: datum.usageMetadata?.totalTokenCount || 0
						});
					} else if (candidate.finishReason && candidate.finishReason !== "STOP") {
						require_logger.logger.error(`Gemini API error due to finish reason: ${candidate.finishReason}.`);
						return { error: `Finish reason ${candidate.finishReason}: ${JSON.stringify(data)}` };
					} else if (candidate.content?.parts) output = require_util$1.mergeParts(output, require_util$1.formatCandidateContents(candidate));
					else return { error: `No output found in response: ${JSON.stringify(data)}` };
				}
				const lastData = dataWithResponse[dataWithResponse.length - 1];
				const promptTokenCount = lastData.usageMetadata?.promptTokenCount;
				const completionTokenCount = lastData.usageMetadata?.candidatesTokenCount;
				const thoughtsTokenCount = lastData.usageMetadata?.thoughtsTokenCount;
				const tokenUsage = {
					total: lastData.usageMetadata?.totalTokenCount || 0,
					prompt: promptTokenCount || 0,
					completion: completionTokenCount || 0,
					...thoughtsTokenCount !== void 0 && { completionDetails: {
						reasoning: thoughtsTokenCount,
						acceptedPrediction: 0,
						rejectedPrediction: 0
					} }
				};
				const completionForCost = completionTokenCount == null ? void 0 : completionTokenCount + (thoughtsTokenCount ?? 0);
				const cost = require_util$1.calculateGoogleCost(this.modelName, config, promptTokenCount, completionForCost, true);
				response = {
					cached: false,
					output,
					tokenUsage,
					cost,
					metadata: {}
				};
				const grounding = require_util$1.collectGroundingMetadata(dataWithResponse);
				if (Object.keys(grounding).length > 0) response.metadata = { ...grounding };
				if (require_cache.isCacheEnabled()) await cache.set(cacheKey, JSON.stringify(response));
			} catch (err) {
				return { error: `Gemini API response error: ${String(err)}. Response data: ${JSON.stringify(data)}` };
			}
		}
		try {
			if (!toolsDisabled && config.functionToolCallbacks && require_logger.isValidJson(response.output)) {
				const structured_output = JSON.parse(response.output);
				if (structured_output.functionCall) {
					const results = [];
					const functionName = structured_output.functionCall.name;
					if (config.functionToolCallbacks[functionName]) try {
						const functionResult = await this.executeFunctionCallback(functionName, JSON.stringify(typeof structured_output.functionCall.args === "string" ? JSON.parse(structured_output.functionCall.args) : structured_output.functionCall.args), config);
						results.push(functionResult);
					} catch (error) {
						require_logger.logger.error(`Error executing function ${functionName}: ${error}`);
					}
					if (results.length > 0) response = {
						...response,
						output: results.join("\n")
					};
				}
			}
		} catch (err) {
			return { error: `Tool callback error: ${String(err)}.` };
		}
		return response;
	}
	async callPalm2Api(prompt) {
		const body = {
			instances: require_fetch.parseChatPrompt(prompt, [{ messages: [{
				author: "user",
				content: prompt
			}] }]),
			parameters: {
				context: this.config.context,
				examples: this.config.examples,
				safetySettings: require_util$1.normalizeSafetySettings(this.config.safetySettings),
				stopSequences: this.config.stopSequences,
				temperature: this.config.temperature,
				maxOutputTokens: this.config.maxOutputTokens,
				topP: this.config.topP,
				topK: this.config.topK
			}
		};
		const cache = await require_cache.getCache();
		const apiHost = this.getApiHost();
		const cacheKey = getVertexBodyCacheKey(`vertex:palm2:${this.modelName}`, body, apiHost);
		let cachedResponse;
		if (require_cache.isCacheEnabled()) {
			cachedResponse = await cache.get(cacheKey);
			if (cachedResponse) {
				const parsedCachedResponse = JSON.parse(cachedResponse);
				const tokenUsage = parsedCachedResponse.tokenUsage;
				if (tokenUsage) tokenUsage.cached = tokenUsage.total;
				require_logger.logger.debug("Returning cached Vertex Palm2 response", {
					model: this.modelName,
					cacheKey
				});
				return {
					...parsedCachedResponse,
					cached: true
				};
			}
		}
		let data;
		try {
			const client = await this.getClientWithCredentials();
			const projectId = await this.getProjectId();
			const url = `https://${apiHost}/${this.getApiVersion()}/projects/${projectId}/locations/${this.getRegion()}/publishers/${this.getPublisher()}/models/${this.modelName}:predict`;
			data = (await client.request({
				url,
				method: "POST",
				headers: { "Content-Type": "application/json" },
				data: body,
				timeout: require_fetch.getRequestTimeoutMs()
			})).data;
		} catch (err) {
			return { error: `API call error: ${JSON.stringify(err)}` };
		}
		try {
			if (data.error) return { error: `Error ${data.error.code}: ${data.error.message}` };
			const prediction = data.predictions?.[0];
			if (!prediction?.candidates?.length) return { error: `No valid predictions returned from API: ${JSON.stringify(data)}` };
			const response = {
				output: prediction.candidates[0].content,
				cached: false
			};
			if (require_cache.isCacheEnabled()) await cache.set(cacheKey, JSON.stringify(response));
			return response;
		} catch (err) {
			return { error: `API response error: ${String(err)}: ${JSON.stringify(data)}` };
		}
	}
	async callLlamaApi(prompt, _context) {
		const region = this.getRegion();
		if (region !== "us-central1") return { error: `Llama models are only available in the us-central1 region. Current region: ${region}. Please set region: 'us-central1' in your configuration.` };
		const messages = require_fetch.parseChatPrompt(prompt, [{
			role: "user",
			content: prompt
		}]);
		const llamaGuardSettings = this.config.llamaConfig?.safetySettings?.llama_guard_settings;
		if (llamaGuardSettings !== void 0 && (typeof llamaGuardSettings !== "object" || llamaGuardSettings === null)) return { error: `Invalid llama_guard_settings: must be an object, received ${typeof llamaGuardSettings}` };
		const modelSafetySettings = {
			enabled: this.config.llamaConfig?.safetySettings?.enabled !== false,
			llama_guard_settings: llamaGuardSettings || {}
		};
		const body = {
			model: `meta/${this.modelName}`,
			messages,
			max_tokens: this.config.maxOutputTokens || 1024,
			stream: false,
			temperature: this.config.temperature,
			top_p: this.config.topP,
			top_k: this.config.topK,
			extra_body: { google: { model_safety_settings: modelSafetySettings } }
		};
		const cache = await require_cache.getCache();
		const apiHost = this.getApiHost();
		const cacheKey = getVertexBodyCacheKey(`vertex:llama:${this.modelName}`, body, apiHost);
		require_logger.logger.debug("Preparing to call Llama API", {
			model: this.modelName,
			region: this.getRegion(),
			messageCount: messages.length,
			maxTokens: body.max_tokens,
			temperature: body.temperature,
			topP: body.top_p,
			topK: body.top_k,
			safetySettingsEnabled: modelSafetySettings.enabled,
			llamaGuardSettingCount: Object.keys(modelSafetySettings.llama_guard_settings).length,
			cacheKey
		});
		let cachedResponse;
		if (require_cache.isCacheEnabled()) {
			cachedResponse = await cache.get(cacheKey);
			if (cachedResponse) {
				const parsedCachedResponse = JSON.parse(cachedResponse);
				const tokenUsage = parsedCachedResponse.tokenUsage;
				if (tokenUsage) tokenUsage.cached = tokenUsage.total;
				require_logger.logger.debug("Returning cached Vertex Llama response", {
					model: this.modelName,
					cacheKey
				});
				return {
					...parsedCachedResponse,
					cached: true
				};
			}
		}
		let data;
		try {
			const client = await this.getClientWithCredentials();
			const url = `https://${apiHost}/v1beta1/projects/${await this.getProjectId()}/locations/${this.getRegion()}/endpoints/openapi/chat/completions`;
			data = (await client.request({
				url,
				method: "POST",
				headers: { "Content-Type": "application/json; charset=utf-8" },
				data: body,
				timeout: require_fetch.getRequestTimeoutMs()
			})).data;
			require_logger.logger.debug("Llama API response", {
				choiceCount: data.choices?.length ?? 0,
				hasUsage: data.usage !== void 0,
				totalTokens: data.usage?.total_tokens,
				promptTokens: data.usage?.prompt_tokens,
				completionTokens: data.usage?.completion_tokens
			});
		} catch (err) {
			const error = err;
			if (error.response && error.response.data) {
				require_logger.logger.debug("Llama API error", {
					status: error.response.status,
					statusText: error.response.statusText,
					hasResponseData: error.response.data !== void 0
				});
				return { error: `API call error: ${JSON.stringify(error.response.data)}` };
			}
			require_logger.logger.debug("Llama API error", { error: err instanceof Error ? err.message : String(err) });
			return { error: `API call error: ${String(err)}` };
		}
		try {
			let output = "";
			if (data.choices && data.choices.length > 0) output = data.choices[0].message.content;
			if (!output) return { error: `No output found in Llama API response: ${JSON.stringify(data)}` };
			const tokenUsage = {
				total: data.usage?.total_tokens || 0,
				prompt: data.usage?.prompt_tokens || 0,
				completion: data.usage?.completion_tokens || 0,
				numRequests: 1
			};
			const response = {
				cached: false,
				output,
				tokenUsage
			};
			if (require_cache.isCacheEnabled()) await cache.set(cacheKey, JSON.stringify(response));
			return response;
		} catch (err) {
			return { error: `Llama API response error: ${String(err)}. Response data: ${JSON.stringify(data)}` };
		}
	}
};
var VertexEmbeddingProvider = class {
	modelName;
	config;
	env;
	constructor(modelName, options = {}) {
		this.modelName = modelName;
		this.config = options.config || {};
		this.env = options.env;
	}
	/**
	* Helper method to get Google client with credentials support
	*/
	async getClientWithCredentials() {
		const { client } = await require_util$1.getGoogleClient({
			credentials: require_util$1.loadCredentials(this.config.credentials),
			googleAuthOptions: this.config.googleAuthOptions,
			scopes: this.config.scopes,
			keyFilename: this.config.keyFilename
		});
		return client;
	}
	id() {
		return `vertex:${this.modelName}`;
	}
	getRegion() {
		return this.config.region || "us-central1";
	}
	getApiVersion() {
		return this.config.apiVersion || "v1";
	}
	getApiHost() {
		return getVertexApiHost(this.getRegion(), this.config.apiHost, this.env);
	}
	async getProjectId() {
		return await require_util$1.resolveProjectId(this.config, this.env);
	}
	async callApi() {
		throw new Error("Vertex API does not provide text inference.");
	}
	async callEmbeddingApi(input) {
		const body = {
			instances: [{ content: input }],
			parameters: { autoTruncate: this.config.autoTruncate || false }
		};
		let data = {};
		try {
			const client = await this.getClientWithCredentials();
			const projectId = await this.getProjectId();
			const url = `https://${this.getApiHost()}/${this.getApiVersion()}/projects/${projectId}/locations/${this.getRegion()}/publishers/google/models/${this.modelName}:predict`;
			data = (await client.request({
				url,
				method: "POST",
				data: body
			})).data;
		} catch (err) {
			require_logger.logger.error(`Vertex API call error: ${err}`);
			throw err;
		}
		require_logger.logger.debug(`Vertex embeddings API response: ${JSON.stringify(data)}`);
		const embeddingData = (data.predictions?.[0])?.embeddings;
		if (!embeddingData?.values) {
			const errorMsg = `No valid embeddings returned from API: ${JSON.stringify(data)}`;
			require_logger.logger.error(errorMsg);
			throw new Error(errorMsg);
		}
		return {
			embedding: embeddingData.values,
			tokenUsage: {
				total: embeddingData.statistics?.token_count ?? 0,
				numRequests: 1
			}
		};
	}
};
const DEFAULT_VERTEX_MODEL = "gemini-3.1-pro-preview";
const DEFAULT_VERTEX_REGION = "global";
const DEFAULT_VERTEX_EMBEDDING_MODEL = "gemini-embedding-001";
function getGoogleVertexEmbeddingProvider(env) {
	return new VertexEmbeddingProvider(DEFAULT_VERTEX_EMBEDDING_MODEL, { env });
}
function getGoogleVertexProviders(env) {
	const gradingProvider = new VertexChatProvider(DEFAULT_VERTEX_MODEL, {
		env,
		config: { region: DEFAULT_VERTEX_REGION }
	});
	return {
		embeddingProvider: getGoogleVertexEmbeddingProvider(env),
		gradingJsonProvider: gradingProvider,
		gradingProvider,
		suggestionsProvider: gradingProvider,
		synthesizeProvider: gradingProvider
	};
}
//#endregion
Object.defineProperty(exports, "getGoogleVertexEmbeddingProvider", {
	enumerable: true,
	get: function() {
		return getGoogleVertexEmbeddingProvider;
	}
});
Object.defineProperty(exports, "getGoogleVertexProviders", {
	enumerable: true,
	get: function() {
		return getGoogleVertexProviders;
	}
});
Object.defineProperty(exports, "vertex_exports", {
	enumerable: true,
	get: function() {
		return vertex_exports;
	}
});

//# sourceMappingURL=vertex-DW4sDd4h.cjs.map