import { calculateCost } from "../utils/costs.js";

//#region src/integrations/opentelemetry.ts
var AmplitudeAgentExporter = class {
	_ai;
	_defaultUserId;
	constructor(options) {
		this._ai = options.amplitudeAI;
		this._defaultUserId = options.defaultUserId ?? "otel-user";
	}
	export(spans, resultCallback) {
		for (const span of spans) try {
			this._processSpan(span);
		} catch {}
		resultCallback({ code: 0 });
	}
	shutdown() {
		return Promise.resolve();
	}
	forceFlush() {
		this._ai.flush();
		return Promise.resolve();
	}
	_processSpan(span) {
		const attrs = span.attributes ?? {};
		const providerName = attrs["gen_ai.provider.name"] ?? attrs["gen_ai.system"];
		if (!providerName) return;
		const startNanos = Number(span.startTimeUnixNano ?? 0);
		const latencyMs = (Number(span.endTimeUnixNano ?? 0) - startNanos) / 1e6;
		const isError = span.status?.code === 2;
		const spanCtx = span.spanContext?.();
		const operation = attrs["gen_ai.operation.name"] ?? attrs["gen_ai.operation"];
		const userId = _normalizeOtelString(attrs["amplitude.user_id"]) ?? this._defaultUserId;
		const sessionId = _normalizeOtelString(attrs["amplitude.session_id"]) ?? "otel-session";
		const modelName = String(attrs["gen_ai.response.model"] ?? attrs["gen_ai.request.model"] ?? "unknown");
		if (operation === "tool" || operation === "tool_call" || operation === "execute_tool") {
			this._ai.trackToolCall({
				userId,
				toolName: String(attrs["gen_ai.tool.name"] ?? span.name ?? "tool"),
				latencyMs,
				success: !isError,
				sessionId,
				traceId: spanCtx?.traceId,
				input: attrs["gen_ai.tool.arguments"] ?? attrs["gen_ai.request.prompt"] ?? void 0,
				output: attrs["gen_ai.response.text"] ?? void 0,
				errorMessage: isError ? span.status?.message : void 0
			});
			return;
		}
		if (operation === "embedding" || operation === "embeddings") {
			this._ai.trackEmbedding({
				userId,
				model: modelName,
				provider: providerName,
				latencyMs,
				sessionId,
				traceId: spanCtx?.traceId,
				inputTokens: attrs["gen_ai.usage.input_tokens"],
				dimensions: attrs["gen_ai.embedding.vector_size"] ?? attrs["gen_ai.response.embedding_dimensions"] ?? attrs["gen_ai.embeddings.dimension.count"]
			});
			return;
		}
		const inputMessages = attrs["gen_ai.input.messages"];
		if (inputMessages != null) {
			const messages = typeof inputMessages === "string" ? _tryParseJsonArray(inputMessages) : Array.isArray(inputMessages) ? inputMessages : [];
			for (const msg of messages) {
				const m = msg;
				if (m?.role === "user" && typeof m.content === "string" && m.content.length > 0) this._ai.trackUserMessage({
					userId,
					content: m.content,
					sessionId,
					traceId: spanCtx?.traceId
				});
			}
		}
		const inputTokens = _toOtelNumber(attrs["gen_ai.usage.input_tokens"]);
		const outputTokens = _toOtelNumber(attrs["gen_ai.usage.output_tokens"]);
		const totalTokens = inputTokens != null || outputTokens != null ? (inputTokens ?? 0) + (outputTokens ?? 0) : void 0;
		const cacheReadTokens = _toOtelNumber(attrs["gen_ai.usage.cache_read.input_tokens"]);
		const cacheCreationTokens = _toOtelNumber(attrs["gen_ai.usage.cache_creation.input_tokens"]);
		let costUsd = _toOtelNumber(attrs["gen_ai.usage.cost"]);
		if (costUsd == null && modelName !== "unknown" && inputTokens != null && outputTokens != null) try {
			const computed = calculateCost({
				modelName,
				inputTokens,
				outputTokens,
				cacheReadInputTokens: cacheReadTokens ?? 0,
				cacheCreationInputTokens: cacheCreationTokens ?? 0,
				defaultProvider: providerName && providerName !== "unknown" ? providerName : void 0
			});
			if (computed > 0) costUsd = computed;
		} catch {}
		this._ai.trackAiMessage({
			userId,
			content: String(attrs["gen_ai.response.text"] ?? ""),
			sessionId,
			model: modelName,
			provider: providerName,
			latencyMs,
			traceId: spanCtx?.traceId,
			inputTokens,
			outputTokens,
			totalTokens,
			cacheReadTokens,
			cacheCreationTokens,
			totalCostUsd: costUsd,
			finishReason: _normalizeFinishReason(attrs["gen_ai.response.finish_reasons"]),
			isError,
			errorMessage: isError ? span.status?.message : void 0,
			temperature: _toOtelNumber(attrs["gen_ai.request.temperature"]),
			maxOutputTokens: _toOtelNumber(attrs["gen_ai.request.max_tokens"]),
			topP: _toOtelNumber(attrs["gen_ai.request.top_p"])
		});
	}
};
const AmplitudeGenAIExporter = AmplitudeAgentExporter;
const AmplitudeSpanExporter = AmplitudeAgentExporter;
function _normalizeFinishReason(value) {
	if (typeof value === "string") return value;
	if (Array.isArray(value)) {
		const first = value[0];
		return typeof first === "string" ? first : void 0;
	}
}
function _toOtelNumber(value) {
	if (typeof value === "number") return value;
	if (typeof value === "string") {
		const parsed = Number(value);
		return Number.isNaN(parsed) ? void 0 : parsed;
	}
}
function _tryParseJsonArray(value) {
	try {
		const parsed = JSON.parse(value);
		return Array.isArray(parsed) ? parsed : [];
	} catch {
		return [];
	}
}
function _normalizeOtelString(value) {
	if (typeof value === "string" && value.length > 0) return value;
	if (typeof value === "number" || typeof value === "boolean") return String(value);
}

//#endregion
export { AmplitudeAgentExporter, AmplitudeGenAIExporter, AmplitudeSpanExporter };
//# sourceMappingURL=opentelemetry.js.map