import { i as logger_default, w as cliState_default } from "./logger-BudIH0qK.js";
import { r as importModule } from "./esm-C5zIToiC.js";
import { t as fetchWithProxy } from "./fetch-D70iPJNm.js";
import { t as OpenAiGenericProvider } from "./openai-0a7Nnw31.js";
import path from "path";
import { BatchTraceProcessor, addTraceProcessor, getOrCreateTrace, run, startTraceExportLoop } from "@openai/agents";

//#region src/providers/openai/agents-loader.ts
/**
* Load agent definition from file path or return inline definition
*/
async function loadAgentDefinition(agentConfig) {
	if (isAgentInstance(agentConfig)) {
		logger_default.debug("[AgentsLoader] Using provided Agent instance");
		return agentConfig;
	}
	if (typeof agentConfig === "string" && agentConfig.startsWith("file://")) {
		logger_default.debug("[AgentsLoader] Loading agent from file", { path: agentConfig });
		return await loadAgentFromFile(agentConfig);
	}
	if (typeof agentConfig === "object") {
		logger_default.debug("[AgentsLoader] Creating agent from inline definition");
		return await createAgentFromDefinition(agentConfig);
	}
	logger_default.debug("[AgentsLoader] Invalid agent configuration", {
		type: typeof agentConfig,
		keys: typeof agentConfig === "object" && agentConfig !== null ? Object.keys(agentConfig).slice(0, 5) : void 0
	});
	throw new Error("Invalid agent configuration: expected Agent instance, file:// URL, or inline definition");
}
/**
* Load agent from file
*/
async function loadAgentFromFile(filePath) {
	const resolvedPath = resolveFilePath(filePath);
	logger_default.debug("[AgentsLoader] Loading agent from resolved path", { path: resolvedPath });
	try {
		const module = await importModule(resolvedPath);
		const agent = module.default || module;
		if (!isAgentInstance(agent)) throw new Error(`File ${resolvedPath} does not export an Agent instance`);
		return agent;
	} catch (error) {
		logger_default.error("[AgentsLoader] Failed to load agent from file", {
			path: resolvedPath,
			error
		});
		throw new Error(`Failed to load agent from ${resolvedPath}: ${error}`);
	}
}
/**
* Create an Agent instance from an inline definition
*/
async function createAgentFromDefinition(definition) {
	try {
		const { Agent } = await import("@openai/agents");
		return new Agent({
			name: definition.name,
			instructions: definition.instructions,
			model: definition.model,
			handoffDescription: definition.handoffDescription,
			outputType: definition.outputType,
			tools: definition.tools,
			handoffs: definition.handoffs
		});
	} catch (error) {
		logger_default.error("[AgentsLoader] Failed to create agent from definition", {
			name: definition?.name,
			model: definition?.model,
			toolCount: definition?.tools?.length,
			handoffCount: definition?.handoffs?.length,
			error
		});
		throw new Error(`Failed to create agent from definition: ${error}`);
	}
}
/**
* Check if a value is an Agent instance
*/
function isAgentInstance(value) {
	return value && typeof value === "object" && "name" in value && "instructions" in value && typeof value.name === "string";
}
/**
* Resolve file:// path to absolute file system path
*/
function resolveFilePath(filePath) {
	const cleanPath = filePath.replace(/^file:\/\//, "");
	if (path.isAbsolute(cleanPath)) return cleanPath;
	const basePath = cliState_default.basePath || process.cwd();
	const resolvedPath = path.resolve(basePath, cleanPath);
	logger_default.debug("[AgentsLoader] Resolved file path", {
		original: filePath,
		basePath,
		resolved: resolvedPath
	});
	return resolvedPath;
}

//#endregion
//#region src/providers/openai/agents-tracing.ts
/**
* OTLP Tracing Exporter for OpenAI Agents
*
* Exports traces and spans from openai-agents-js to promptfoo's OTLP receiver
* in OTLP JSON format over HTTP.
*/
var OTLPTracingExporter = class {
	otlpEndpoint;
	evaluationId;
	testCaseId;
	constructor(options = {}) {
		this.otlpEndpoint = options.otlpEndpoint || "http://localhost:4318";
		this.evaluationId = options.evaluationId;
		this.testCaseId = options.testCaseId;
	}
	/**
	* Export traces and spans to OTLP endpoint
	*/
	async export(items, signal) {
		if (items.length === 0) {
			logger_default.debug("[AgentsTracing] No items to export");
			return;
		}
		logger_default.debug(`[AgentsTracing] Exporting ${items.length} items to OTLP`);
		try {
			const otlpPayload = this.transformToOTLP(items);
			const url = `${this.otlpEndpoint}/v1/traces`;
			logger_default.debug("[AgentsTracing] Sending OTLP payload", {
				url,
				spanCount: otlpPayload.resourceSpans[0]?.scopeSpans[0]?.spans?.length || 0
			});
			const response = await fetchWithProxy(url, {
				method: "POST",
				headers: { "Content-Type": "application/json" },
				body: JSON.stringify(otlpPayload),
				signal
			});
			if (response.ok) logger_default.debug("[AgentsTracing] Successfully exported traces to OTLP");
			else logger_default.error(`[AgentsTracing] OTLP export failed: ${response.status} ${response.statusText}`);
		} catch (error) {
			logger_default.error("[AgentsTracing] Failed to export traces to OTLP", { error });
		}
	}
	/**
	* Transform openai-agents-js traces/spans to OTLP JSON format
	*/
	transformToOTLP(items) {
		const spans = items.filter((item) => item.type === "trace.span").map((item) => this.spanToOTLP(item));
		return { resourceSpans: [{
			resource: { attributes: [
				{
					key: "service.name",
					value: { stringValue: "promptfoo-agents" }
				},
				...this.evaluationId ? [{
					key: "evaluation.id",
					value: { stringValue: this.evaluationId }
				}] : [],
				...this.testCaseId ? [{
					key: "test.case.id",
					value: { stringValue: this.testCaseId }
				}] : []
			] },
			scopeSpans: [{
				scope: {
					name: "openai-agents-js",
					version: "0.1.0"
				},
				spans
			}]
		}] };
	}
	/**
	* Convert a single span to OTLP format
	*/
	spanToOTLP(span) {
		const startTime = span.startedAt ? new Date(span.startedAt).getTime() : Date.now();
		const endTime = span.endedAt ? new Date(span.endedAt).getTime() : void 0;
		const traceId = span.traceId || this.generateTraceId();
		const spanId = span.spanId || this.generateSpanId();
		return {
			traceId: this.hexToBase64(traceId, "trace"),
			spanId: this.hexToBase64(spanId, "span"),
			parentSpanId: span.parentId ? this.hexToBase64(span.parentId, "span") : void 0,
			name: this.getSpanName(span),
			kind: 1,
			startTimeUnixNano: String(startTime * 1e6),
			endTimeUnixNano: endTime ? String(endTime * 1e6) : void 0,
			attributes: this.attributesToOTLP(span.spanData),
			status: this.getSpanStatus(span)
		};
	}
	/**
	* Get span name from span data
	*/
	getSpanName(span) {
		const data = span.spanData;
		if ("name" in data && data.name) return data.name;
		if (data.type) return `agent.${data.type}`;
		return "agent.span";
	}
	/**
	* Get span status from span data
	*/
	getSpanStatus(span) {
		const error = span.error;
		if (error) return {
			code: 2,
			message: error.message || String(error)
		};
		return { code: 0 };
	}
	/**
	* Convert span data to OTLP attributes
	*/
	attributesToOTLP(data) {
		const attributes = [];
		if (!data) return attributes;
		for (const [key, value] of Object.entries(data)) {
			if (key === "name" || key === "type") continue;
			attributes.push({
				key: `agent.${key}`,
				value: this.valueToOTLP(value)
			});
		}
		return attributes;
	}
	/**
	* Convert a value to OTLP attribute value format
	*/
	valueToOTLP(value) {
		if (value === null || value === void 0) return { stringValue: "" };
		if (typeof value === "string") return { stringValue: value };
		if (typeof value === "number") return Number.isInteger(value) ? { intValue: String(value) } : { doubleValue: value };
		if (typeof value === "boolean") return { boolValue: value };
		if (Array.isArray(value)) return { arrayValue: { values: value.map((v) => this.valueToOTLP(v)) } };
		if (typeof value === "object") return { stringValue: JSON.stringify(value) };
		return { stringValue: String(value) };
	}
	/**
	* Convert hex string to base64 for OTLP format
	* Handles openai-agents-js ID format (trace_XXX, span_XXX)
	* @param hex - The hex string to convert
	* @param kind - Whether this is a 'trace' (16 bytes) or 'span' (8 bytes) ID
	*/
	hexToBase64(hex, kind) {
		if (!hex) return "";
		try {
			let cleanHex = hex.replace(/^(trace_|span_|group_)/, "");
			const targetLength = kind === "span" ? 16 : 32;
			if (cleanHex.length > targetLength) cleanHex = cleanHex.substring(0, targetLength);
			else if (cleanHex.length < targetLength) cleanHex = cleanHex.padEnd(targetLength, "0");
			return Buffer.from(cleanHex, "hex").toString("base64");
		} catch (error) {
			logger_default.error(`[AgentsTracing] Failed to convert hex to base64: ${hex}`, { error });
			const fallbackLen = kind === "span" ? 16 : 32;
			return Buffer.from(this.generateRandomHex(fallbackLen), "hex").toString("base64");
		}
	}
	/**
	* Generate a random trace ID (32 hex chars)
	*/
	generateTraceId() {
		return this.generateRandomHex(32);
	}
	/**
	* Generate a random span ID (16 hex chars)
	*/
	generateSpanId() {
		return this.generateRandomHex(16);
	}
	/**
	* Generate random hex string of specified length
	*/
	generateRandomHex(length) {
		const bytes = Math.ceil(length / 2);
		const buffer = Buffer.alloc(bytes);
		for (let i = 0; i < bytes; i++) buffer[i] = Math.floor(Math.random() * 256);
		return buffer.toString("hex").substring(0, length);
	}
};

//#endregion
//#region src/providers/openai/agents.ts
/**
* OpenAI Agents Provider
*
* Integrates openai-agents-js SDK as a promptfoo provider.
* Supports multi-turn agent workflows with tools, handoffs, and tracing.
*/
var OpenAiAgentsProvider = class extends OpenAiGenericProvider {
	agentConfig;
	agent;
	tracingExporter;
	constructor(modelName, options = {}) {
		super(modelName, options);
		this.agentConfig = options.config || {};
	}
	id() {
		return `openai:agents:${this.modelName}`;
	}
	toString() {
		return `[OpenAI Agents Provider ${this.modelName}]`;
	}
	/**
	* Call the agent with the given prompt
	*/
	async callApi(prompt, context, callApiOptions) {
		logger_default.debug("[AgentsProvider] Starting agent call", {
			prompt: prompt.substring(0, 100),
			hasContext: !!context
		});
		try {
			if (!this.agent) this.agent = await this.initializeAgent();
			await this.setupTracingIfNeeded(context);
			const result = await this.runAgent(prompt, context, callApiOptions);
			logger_default.debug("[AgentsProvider] Agent run completed", {
				outputLength: result.output?.length || 0,
				tokenUsage: result.tokenUsage
			});
			return result;
		} catch (error) {
			logger_default.error("[AgentsProvider] Agent call failed", { error });
			throw error;
		}
	}
	/**
	* Initialize the agent from configuration
	*/
	async initializeAgent() {
		logger_default.debug("[AgentsProvider] Initializing agent");
		if (!this.agentConfig.agent) throw new Error("No agent configuration provided");
		try {
			const agent = await loadAgentDefinition(this.agentConfig.agent);
			logger_default.debug("[AgentsProvider] Agent initialized successfully", { name: agent.name });
			return agent;
		} catch (error) {
			logger_default.error("[AgentsProvider] Failed to initialize agent", { error });
			throw new Error(`Failed to initialize agent: ${error}`);
		}
	}
	/**
	* Setup tracing if enabled
	*/
	async setupTracingIfNeeded(context) {
		if (!(this.agentConfig.tracing === true || context?.test?.metadata?.tracingEnabled === true || process.env.PROMPTFOO_TRACING_ENABLED === "true")) {
			logger_default.debug("[AgentsProvider] Tracing not enabled");
			return;
		}
		logger_default.debug("[AgentsProvider] Setting up tracing");
		try {
			this.tracingExporter = new OTLPTracingExporter({
				otlpEndpoint: this.agentConfig.otlpEndpoint,
				evaluationId: context?.evaluationId,
				testCaseId: context?.testCaseId
			});
			await this.registerTracingExporter(this.tracingExporter);
			startTraceExportLoop();
			logger_default.debug("[AgentsProvider] Tracing setup complete");
		} catch (error) {
			logger_default.error("[AgentsProvider] Failed to setup tracing", { error });
		}
	}
	/**
	* Register tracing exporter with openai-agents-js tracing system
	*/
	async registerTracingExporter(exporter) {
		try {
			addTraceProcessor(new BatchTraceProcessor(exporter, {
				maxQueueSize: 100,
				maxBatchSize: 10,
				scheduleDelay: 1e3
			}));
			logger_default.debug("[AgentsProvider] Tracing processor registered");
		} catch (error) {
			logger_default.error("[AgentsProvider] Failed to register tracing processor", { error });
			throw error;
		}
	}
	/**
	* Run the agent with the given prompt
	*/
	async runAgent(prompt, context, callApiOptions) {
		try {
			logger_default.debug("[AgentsProvider] Running agent", {
				agentName: this.agent?.name,
				maxTurns: this.agentConfig.maxTurns || 10
			});
			const runOptions = {
				context: context?.vars,
				maxTurns: this.agentConfig.maxTurns || 10,
				signal: callApiOptions?.abortSignal
			};
			if (this.agentConfig.model || this.modelName) runOptions.model = this.agentConfig.model || this.modelName;
			if (this.agentConfig.modelSettings) runOptions.modelSettings = this.agentConfig.modelSettings;
			const result = await getOrCreateTrace(async () => {
				return await run(this.agent, prompt, runOptions);
			});
			logger_default.debug("[AgentsProvider] Agent run result", {
				hasOutput: !!result.finalOutput,
				turns: result.newItems?.length || 0
			});
			return {
				output: result.finalOutput,
				tokenUsage: this.extractTokenUsage(result),
				cached: false,
				cost: this.calculateCost(result)
			};
		} catch (error) {
			logger_default.error("[AgentsProvider] Failed to run agent", { error });
			throw error;
		}
	}
	/**
	* Extract token usage from agent result
	*/
	extractTokenUsage(result) {
		if (!result.usage) return {};
		const usage = result.usage;
		return {
			total: usage.totalTokens || void 0,
			prompt: usage.promptTokens || void 0,
			completion: usage.completionTokens || void 0
		};
	}
	/**
	* Calculate cost from agent result
	*/
	calculateCost(_result) {}
};

//#endregion
export { OpenAiAgentsProvider };
//# sourceMappingURL=agents-D2NFWM4l.js.map