// @bun
var __defProp = Object.defineProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, {
      get: all[name],
      enumerable: true,
      configurable: true,
      set: (newValue) => all[name] = () => newValue
    });
};
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
var __require = import.meta.require;

// src/telemetry/posthog.ts
var exports_posthog = {};
__export(exports_posthog, {
  createPostHogTracedModel: () => createPostHogTracedModel,
  createPostHogTelemetryCollector: () => createPostHogTelemetryCollector,
  createCompositeTelemetryCollector: () => createCompositeTelemetryCollector,
  PostHogTelemetryCollector: () => PostHogTelemetryCollector,
  CompositeTelemetryCollector: () => CompositeTelemetryCollector
});
async function createPostHogTracedModel(model, config, overrides) {
  const { withTracing } = await importPostHogAI();
  const phClient = await resolvePostHogClient(config);
  const tracingOptions = {
    ...config.defaults,
    ...overrides
  };
  return withTracing(model, phClient, tracingOptions);
}

class PostHogTelemetryCollector {
  phClient;
  config;
  initPromise;
  constructor(config) {
    this.config = config;
    this.phClient = config.client;
  }
  async collect(sample) {
    const client = await this.getClient();
    const metadata = asRecord(sample.metadata);
    const distinctId = this.config.defaults?.posthogDistinctId ?? asString(metadata["actorId"]) ?? "system";
    const traceId = asString(metadata["traceId"]) ?? this.config.defaults?.posthogTraceId;
    const sessionId = asString(metadata["sessionId"]);
    const telemetryEvent = asString(metadata["telemetryEvent"]);
    const event = telemetryEvent === "span" ? "$ai_span" : "$ai_generation";
    const tokenUsage = metadata["tokenUsage"];
    const totalUsage = metadata["totalUsage"];
    const errorMessage = asString(metadata["errorMessage"]);
    client.capture({
      distinctId,
      event,
      properties: {
        $ai_model: asString(metadata["responseModelId"]) ?? sample.operation.name,
        $ai_provider: asString(metadata["provider"]) ?? "contractspec",
        $ai_latency: sample.durationMs / 1000,
        $ai_is_error: !sample.success,
        $ai_error: !sample.success ? errorMessage : undefined,
        $ai_trace_id: traceId,
        $ai_session_id: sessionId,
        $ai_span_id: asString(metadata["spanId"]),
        $ai_parent_id: asString(metadata["parentSpanId"]),
        $ai_span_name: asString(metadata["spanName"]) ?? sample.operation.name,
        ...tokenUsage ? mapTokenUsage(tokenUsage) : {},
        ...totalUsage ? mapTotalUsage(totalUsage) : {},
        $ai_http_status: asNumber(metadata["httpStatus"]),
        $ai_request_url: asString(metadata["requestUrl"]),
        $ai_base_url: asString(metadata["baseUrl"]),
        ...this.config.defaults?.posthogProperties,
        contractspec_operation: sample.operation.name,
        contractspec_version: sample.operation.version,
        contractspec_agent_id: asString(metadata["agentId"]),
        contractspec_tenant_id: asString(metadata["tenantId"]),
        contractspec_actor_id: asString(metadata["actorId"]),
        contractspec_step_index: asNumber(metadata["stepIndex"]),
        contractspec_step_started_at: asDateIso(metadata["stepStartedAt"]),
        contractspec_finish_reason: asString(metadata["finishReason"]),
        contractspec_finish_reason_raw: asString(metadata["rawFinishReason"]),
        contractspec_tool_count: asNumber(metadata["toolCallCount"]),
        contractspec_tool_name: asString(metadata["toolName"]),
        contractspec_tool_call_args: metadata["toolCallArgs"],
        contractspec_tool_result_output: metadata["toolResultOutput"],
        contractspec_provider_metadata: metadata["providerMetadata"],
        contractspec_step_warnings: metadata["warnings"],
        contractspec_response_id: asString(metadata["responseId"]),
        contractspec_response_model_id: asString(metadata["responseModelId"]),
        contractspec_response_timestamp: asDateIso(metadata["responseTimestamp"]),
        contractspec_response_headers: metadata["responseHeaders"],
        contractspec_response_body: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["responseBody"],
        contractspec_response_messages: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["responseMessages"],
        contractspec_request_headers: metadata["requestHeaders"],
        contractspec_request_body: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["requestBody"],
        contractspec_step_text: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["stepText"],
        contractspec_step_reasoning_text: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["stepReasoningText"]
      },
      groups: this.config.defaults?.posthogGroups
    });
  }
  async shutdown() {
    if (this.phClient?.shutdown) {
      await this.phClient.shutdown();
    }
  }
  async getClient() {
    if (this.phClient)
      return this.phClient;
    if (!this.initPromise) {
      this.initPromise = resolvePostHogClient(this.config).then((client) => {
        this.phClient = client;
        return client;
      });
    }
    return this.initPromise;
  }
}
function createPostHogTelemetryCollector(config) {
  return new PostHogTelemetryCollector(config);
}

class CompositeTelemetryCollector {
  collectors;
  constructor(collectors) {
    this.collectors = collectors;
  }
  async collect(sample) {
    await Promise.all(this.collectors.map((c) => c.collect(sample)));
  }
}
function createCompositeTelemetryCollector(collectors) {
  return new CompositeTelemetryCollector(collectors);
}
async function importPostHogAI() {
  try {
    return await import("@posthog/ai");
  } catch {
    throw new Error("PostHog LLM Analytics requires @posthog/ai to be installed. Run: npm install @posthog/ai posthog-node");
  }
}
async function resolvePostHogClient(config) {
  if (config.client)
    return config.client;
  if (!config.apiKey) {
    throw new Error("PostHog LLM Analytics requires either a client instance or an apiKey.");
  }
  try {
    const { PostHog } = await import("posthog-node");
    return new PostHog(config.apiKey, {
      host: config.host ?? "https://us.i.posthog.com"
    });
  } catch {
    throw new Error("PostHog LLM Analytics requires posthog-node to be installed. Run: npm install posthog-node");
  }
}
function mapTokenUsage(usage) {
  const usageRecord = asRecord(usage);
  const inputTokenDetails = asRecord(usageRecord["inputTokenDetails"]);
  const outputTokenDetails = asRecord(usageRecord["outputTokenDetails"]);
  return {
    $ai_input_tokens: asNumber(usageRecord["inputTokens"]) ?? asNumber(usageRecord["promptTokens"]),
    $ai_output_tokens: asNumber(usageRecord["outputTokens"]) ?? asNumber(usageRecord["completionTokens"]),
    $ai_reasoning_tokens: asNumber(outputTokenDetails["reasoningTokens"]) ?? asNumber(usageRecord["reasoningTokens"]),
    $ai_cache_read_input_tokens: asNumber(inputTokenDetails["cacheReadTokens"]) ?? asNumber(usageRecord["cachedInputTokens"]),
    $ai_cache_creation_input_tokens: asNumber(inputTokenDetails["cacheWriteTokens"]),
    $ai_usage: maybeRecord(usageRecord["raw"]) ?? usageRecord
  };
}
function mapTotalUsage(usage) {
  const usageRecord = asRecord(usage);
  return {
    contractspec_total_input_tokens: asNumber(usageRecord["inputTokens"]),
    contractspec_total_output_tokens: asNumber(usageRecord["outputTokens"]),
    contractspec_total_tokens: asNumber(usageRecord["totalTokens"]),
    contractspec_total_usage_raw: maybeRecord(usageRecord["raw"]) ?? usageRecord
  };
}
function asRecord(value) {
  return value && typeof value === "object" ? value : {};
}
function maybeRecord(value) {
  return value && typeof value === "object" ? value : undefined;
}
function asString(value) {
  return typeof value === "string" && value.length > 0 ? value : undefined;
}
function asNumber(value) {
  return typeof value === "number" ? value : undefined;
}
function asDateIso(value) {
  if (value instanceof Date)
    return value.toISOString();
  return;
}
export {
  createPostHogTracedModel,
  createPostHogTelemetryCollector,
  createCompositeTelemetryCollector,
  PostHogTelemetryCollector,
  CompositeTelemetryCollector
};
