"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ANALYTICS_STATUS_PRIORITY_EXPR = exports.EVAL_RESULTS_LEGACY_CH_TABLE = void 0;
exports.buildWorkspacePulseMetricsGraphSqlDenorm = buildWorkspacePulseMetricsGraphSqlDenorm;
exports.buildWorkspacePulseEvalCountSqlDenorm = buildWorkspacePulseEvalCountSqlDenorm;
exports.buildWorkspacePulseEvalDailySqlDenorm = buildWorkspacePulseEvalDailySqlDenorm;
exports.buildWorkspacePulseTracesEvaluatedSqlDenorm = buildWorkspacePulseTracesEvaluatedSqlDenorm;
exports.buildWorkspacePulseTopFailuresSqlDenorm = buildWorkspacePulseTopFailuresSqlDenorm;
exports.buildMetricFailureTreemapSqlDenorm = buildMetricFailureTreemapSqlDenorm;
exports.buildMetricFailureAnalysisCountSqlDenorm = buildMetricFailureAnalysisCountSqlDenorm;
exports.buildMetricFailureAnalysisInitialTracesCte = buildMetricFailureAnalysisInitialTracesCte;
exports.buildMetricFailureAnalysisListSqlDenorm = buildMetricFailureAnalysisListSqlDenorm;
exports.buildMetricFailureTotalSqlDenorm = buildMetricFailureTotalSqlDenorm;
exports.totalEvaluationsFromComponentCountsSql = totalEvaluationsFromComponentCountsSql;
exports.buildSessionListEvalCteSqlDenorm = buildSessionListEvalCteSqlDenorm;
exports.buildTraceListEvalCteSqlDenorm = buildTraceListEvalCteSqlDenorm;
exports.buildSecurityOverviewSqlDenorm = buildSecurityOverviewSqlDenorm;
exports.buildObserveEvalStatsSqlDenorm = buildObserveEvalStatsSqlDenorm;
exports.buildObserveEvalStatsFilteredSqlDenorm = buildObserveEvalStatsFilteredSqlDenorm;
exports.buildTotalRecordsSqlDenorm = buildTotalRecordsSqlDenorm;
exports.buildAiReliabilitySqlDenorm = buildAiReliabilitySqlDenorm;
const types_1 = require("./types");
const EVAL_RESULTS_TABLE = 'eval_results';
function chLit(value) {
    return value.replace(/'/g, "''");
}
function optionalAppProjectFilter(params, alias) {
    const p = alias ? `${alias}.` : '';
    const parts = [];
    if (params.applicationId) {
        parts.push(`AND ${p}application_id = '${chLit(params.applicationId)}'`);
    }
    if (Array.isArray(params.applicationIds) && params.applicationIds.length > 0) {
        const list = params.applicationIds.map((id) => `'${chLit(id)}'`).join(',');
        parts.push(`AND ${p}application_id IN (${list})`);
    }
    if (params.projectId) {
        parts.push(`AND ${p}project_id = '${chLit(params.projectId)}'`);
    }
    return parts.join('\n      ');
}
function traceScopeFilter(scope) {
    if (scope === 'session') {
        return `AND session_id NOT IN ('', 'null')
      AND session_id IS NOT NULL`;
    }
    return `AND (
    length(trace_ids) > 0
    OR (trace_id IS NOT NULL AND trace_id NOT IN ('', 'null'))
  )`;
}
function traceOrSessionScopeFilter() {
    return `AND (
    length(trace_ids) > 0
    OR (trace_id IS NOT NULL AND trace_id NOT IN ('', 'null'))
    OR (session_id IS NOT NULL AND session_id NOT IN ('', 'null'))
  )`;
}
function workspacePulseScopeFilter() {
    return `AND trace_id NOT IN ('', 'null')
  AND trace_id IS NOT NULL`;
}
function optionalMultiProjectAppFilter(params, alias) {
    const p = alias ? `${alias}.` : '';
    const parts = [];
    if (params.applicationIds.length > 0) {
        const list = params.applicationIds.map((id) => `'${chLit(id)}'`).join(',');
        parts.push(`AND ${p}application_id IN (${list})`);
    }
    if (params.projectIds.length > 0) {
        const list = params.projectIds.map((id) => `'${chLit(id)}'`).join(',');
        parts.push(`AND ${p}project_id IN (${list})`);
    }
    return parts.join('\n  ');
}
/** Functional metrics and security plugins (legacy pulse scope; not is_redteam = 0 only). */
function workspacePulseComponentFilter(alias) {
    const p = alias ? `${alias}.` : '';
    return `AND (${p}metric_key != '' OR ${p}plugin_id != '')
  AND ${p}metric_key != 'human'`;
}
/** Workspace dashboard: daily component pass/fail counts (functional + security trace evals). */
function buildWorkspacePulseMetricsGraphSqlDenorm(params) {
    return `
SELECT
  toDate(created_at) AS date,
  count() AS total,
  countIf(component_pass = 1) AS pass,
  countIf(component_pass = 0 AND failure_reason != 2) AS fail
FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE}
WHERE created_at >= '${chLit(params.start)}' AND created_at <= '${chLit(params.end)}'
  ${workspacePulseComponentFilter()}
  ${workspacePulseScopeFilter()}
  ${optionalMultiProjectAppFilter(params)}
GROUP BY date
ORDER BY date ASC
`.trim();
}
/** Workspace dashboard: distinct production evals (trace or session scoped). */
function buildWorkspacePulseEvalCountSqlDenorm(params) {
    return `
SELECT uniqExact(eval_id) AS total
FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
WHERE created_at >= '${chLit(params.start)}' AND created_at <= '${chLit(params.end)}'
  ${traceOrSessionScopeFilter()}
  ${optionalMultiProjectAppFilter(params)}
`.trim();
}
/** Workspace dashboard: daily distinct eval counts for summary sparkline. */
function buildWorkspacePulseEvalDailySqlDenorm(params) {
    return `
SELECT
  toDate(created_at) AS date,
  uniqExact(eval_id) AS count
FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
WHERE created_at >= '${chLit(params.start)}' AND created_at <= '${chLit(params.end)}'
  ${traceOrSessionScopeFilter()}
  ${optionalMultiProjectAppFilter(params)}
GROUP BY date
ORDER BY date ASC
`.trim();
}
/** Workspace dashboard: distinct traces with at least one eval result. */
function buildWorkspacePulseTracesEvaluatedSqlDenorm(params) {
    return `
SELECT uniqExact(trace_id) AS total
FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
WHERE created_at >= '${chLit(params.start)}' AND created_at <= '${chLit(params.end)}'
  AND trace_id NOT IN ('', 'null')
  AND trace_id IS NOT NULL
  ${optionalMultiProjectAppFilter(params)}
`.trim();
}
/** Workspace dashboard: top failing metrics/plugins (functional + security). */
function buildWorkspacePulseTopFailuresSqlDenorm(params) {
    return `
SELECT
  if(metric_key != '', metric_key, plugin_id) AS metricName,
  CAST(sumIf(component_pass = 0 AND failure_reason != 2, 1) AS UInt64) AS failed,
  CAST(sumIf(component_pass = 1, 1) AS UInt64) AS passed,
  CAST(count() AS UInt64) AS total
FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE}
WHERE created_at >= '${chLit(params.start)}' AND created_at <= '${chLit(params.end)}'
  ${workspacePulseComponentFilter()}
  ${workspacePulseScopeFilter()}
  ${optionalMultiProjectAppFilter(params)}
GROUP BY metricName
HAVING failed > 0 AND metricName != ''
ORDER BY failed DESC, total DESC
LIMIT ${params.limit}
`.trim();
}
/** Treemap success/failure (functional components, trace or session scope). */
function buildMetricFailureTreemapSqlDenorm(params, options) {
    const passFilter = options.componentPassFilter === 0
        ? 'AND component_pass = 0'
        : options.componentPassFilter === 1
            ? 'AND component_pass = 1'
            : '';
    return `
SELECT
  metric_key AS type,
  CAST(sumIf(component_pass = 0 AND failure_reason != 2, 1) AS UInt64) AS failureCount,
  CAST(sumIf(component_pass = 1, 1) AS UInt64) AS successCount,
  CAST(sumIf(error IS NOT NULL AND failure_reason = 2, 1) AS UInt64) AS errorCount,
  avg(component_score) AS avgScore
FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE}
WHERE created_at >= '${chLit(params.start)}' AND created_at <= '${chLit(params.end)}'
  AND is_redteam = 0
  AND metric_key != ''
  ${passFilter}
  ${traceOrSessionScopeFilter()}
  ${optionalAppProjectFilter(params)}
GROUP BY metric_key
ORDER BY metric_key
`.trim();
}
/** Legacy ClickHouse table — prompt/response/detail rows only; list/count use denorm. */
exports.EVAL_RESULTS_LEGACY_CH_TABLE = 'eval_results';
function buildMetricFailureAnalysisComponentMatchSql(params, alias = 'c') {
    const p = alias ? `${alias}.` : '';
    const metricLit = chLit(params.metricName);
    const metricMatch = params.isRedteam === 1
        ? `(
        ${p}plugin_id = '${metricLit}'
        OR ${p}metric_key = '${metricLit}'
        OR ${p}assertion_display_label = '${metricLit}'
        OR ${p}assertion_type = '${metricLit}'
      )`
        : `(
        ${p}metric_key = '${metricLit}'
        OR ${p}assertion_display_label = '${metricLit}'
        OR ${p}assertion_type = '${metricLit}'
      )`;
    let passFilter = ``;
    if (!params.output) {
        if (params.metricType === 'success') {
            passFilter = ` AND ${p}component_pass = 1`;
        }
        else if (params.metricType === 'failure') {
            passFilter = ` AND ${p}component_pass = 0 AND ${p}failure_reason != 2`;
        }
        else {
            passFilter = ` AND ${p}failure_reason != 2`;
        }
    }
    let errorFilter = '';
    if (!params.output && params.metricType === 'error') {
        errorFilter = ` AND ${p}error IS NOT NULL AND ${p}failure_reason = 2`;
    }
    const outputFilter = params.output
        ? ` AND lower(${p}component_reason) = lower('${chLit(params.output)}')`
        : '';
    return `${metricMatch}${passFilter}${errorFilter}${outputFilter}`;
}
/** Paginated metric-failure-analysis: distinct trace or session count. */
function buildMetricFailureAnalysisCountSqlDenorm(params, scope, idRestrictSql = '') {
    const idCol = scope === 'session' ? 'session_id' : 'trace_id';
    return `
SELECT COUNT(DISTINCT c.${idCol}) AS total_records
FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE} AS c
WHERE c.created_at >= '${chLit(params.start)}' AND c.created_at <= '${chLit(params.end)}'
  AND c.is_redteam = ${params.isRedteam}
  AND c.${idCol} NOT IN ('', 'null')
  AND c.${idCol} IS NOT NULL
  ${optionalAppProjectFilter(params, 'c')}
  ${idRestrictSql}
  AND ${buildMetricFailureAnalysisComponentMatchSql(params, 'c')}
`.trim();
}
/** CTE: traces/sessions that have at least one matching component row. */
function buildMetricFailureAnalysisInitialTracesCte(params, scope, idRestrictSql = '') {
    const idCol = scope === 'session' ? 'session_id' : 'trace_id';
    const idAlias = scope === 'session' ? 'sessionId' : 'trace_id';
    return `
initial_traces AS (
  SELECT
    c.${idCol} AS ${idAlias},
    min(c.created_at) AS first_created_at
  FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE} AS c
  WHERE c.created_at >= '${chLit(params.start)}' AND c.created_at <= '${chLit(params.end)}'
    AND c.is_redteam = ${params.isRedteam}
    AND c.${idCol} NOT IN ('', 'null')
    AND c.${idCol} IS NOT NULL
    ${optionalAppProjectFilter(params, 'c')}
    ${idRestrictSql}
    AND ${buildMetricFailureAnalysisComponentMatchSql(params, 'c')}
  GROUP BY c.${idCol}
)`.trim();
}
/** List rows: component aggregates from denorm; prompt from legacy eval_results. */
function buildMetricFailureAnalysisListSqlDenorm(params, scope, options) {
    const idCol = scope === 'session' ? 'session_id' : 'trace_id';
    const idAlias = scope === 'session' ? 'sessionId' : 'trace_id';
    const legacyIdCol = scope === 'session' ? 'sessionId' : 'trace_id';
    const legacyTable = options.legacyEvalTable ?? exports.EVAL_RESULTS_LEGACY_CH_TABLE;
    const otelJoinKey = scope === 'session' ? 'session.id' : 'TraceId';
    const otelPrewhere = scope === 'session'
        ? `SpanAttributes['session.id'] IN (SELECT sessionId FROM paged_traces)`
        : `TraceId IN (SELECT trace_id FROM paged_traces)`;
    const otelSessionSelect = scope === 'session'
        ? `
        SELECT
          SpanAttributes['session.id'] AS sessionId,
          SpanAttributes
        FROM ${options.otelTracesTable}
        PREWHERE ${otelPrewhere}
        WHERE SpanAttributes IS NOT NULL
          AND SpanAttributes['session.id'] NOT IN ('', 'null')
          AND SpanAttributes['session.id'] IS NOT NULL
          AND SpanAttributes['session.id'] != ''
          AND SpanAttributes['session.id'] != 'null'`
        : `
        SELECT
          TraceId,
          SpanAttributes
        FROM ${options.otelTracesTable}
        PREWHERE ${otelPrewhere}
        WHERE SpanAttributes IS NOT NULL`;
    const otelGroupKey = scope === 'session' ? 'sessionId' : 'TraceId';
    const otelJoinOn = scope === 'session'
        ? `pt.sessionId = trace.sessionId`
        : `pt.trace_id = trace.TraceId`;
    return `
WITH
${options.initialTracesCte},

paged_traces AS (
  SELECT ${idAlias}, first_created_at AS created_at
  FROM initial_traces
  ORDER BY first_created_at ASC
  LIMIT ${options.pageLimit} OFFSET ${options.pageOffset}
),

trace_agg AS (
  SELECT
    c.${idCol} AS ${idAlias},
    sumIf(c.component_pass = 1, 1) AS metric_pass_count,
    sumIf(c.component_pass = 0 AND c.failure_reason != 2, 1) AS metric_fail_count,
    sum(c.component_score) AS metric_score_sum,
    count() AS metric_component_total,
    sum(
      if(
        c.failure_reason = 2 AND c.error IS NOT NULL AND c.error != '',
        1,
        0
      )
    ) AS metric_error_count
  FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE} AS c
  WHERE c.${idCol} IN (SELECT ${idAlias} FROM paged_traces)
  GROUP BY c.${idCol}
),

per_trace_meta AS (
  SELECT
    e.${legacyIdCol} AS ${idAlias},
    toJSONString(argMin(e.prompt, e.created_at)) AS prompt_json,
    argMin(e.success, e.created_at) AS success,
    argMin(e.project_id, e.created_at) AS project_id
  FROM ${legacyTable} AS e
  PREWHERE e.${legacyIdCol} IN (SELECT ${idAlias} FROM paged_traces)
  GROUP BY e.${legacyIdCol}
),

trace AS (
  SELECT
    ${otelGroupKey},
    any(SpanAttributes) AS SpanAttributes
  FROM (
    ${otelSessionSelect}
  ) t_inner
  GROUP BY ${otelGroupKey}
)

SELECT
  pt.${idAlias} AS ${idAlias},
  pt.created_at AS created_at,
  ifNull(ta.metric_pass_count, 0) AS metric_pass_count,
  ifNull(ta.metric_fail_count, 0) AS metric_fail_count,
  ifNull(ta.metric_score_sum, 0) AS metric_score_sum,
  ifNull(ta.metric_component_total, 0) AS metric_component_total,
  ifNull(ta.metric_error_count, 0) AS metric_error_count,
  pm.prompt_json AS prompt_json,
  pm.success AS success,
  pm.project_id AS project_id,
  trace.SpanAttributes AS spanAttributes,
  trace.${otelGroupKey} AS ${scope === 'session' ? 'sessionId_' : 'traceId'}
FROM paged_traces AS pt
LEFT JOIN trace_agg AS ta ON pt.${idAlias} = ta.${idAlias}
LEFT JOIN per_trace_meta AS pm ON pt.${idAlias} = pm.${idAlias}
LEFT JOIN trace ON ${otelJoinOn}
ORDER BY pt.created_at ASC
`.trim();
}
/** Denormalized metric failure total (functional / is_redteam = 0). */
function buildMetricFailureTotalSqlDenorm(params, scope, options) {
    const passFilter = options?.componentPassFilter === 0
        ? 'AND component_pass = 0'
        : options?.componentPassFilter === 1
            ? 'AND component_pass = 1'
            : '';
    return `
SELECT
  metric_key AS type,
  CAST(sumIf(component_pass = 0 AND failure_reason != 2, 1) AS UInt64) AS failureCount,
  CAST(sumIf(component_pass = 1, 1) AS UInt64) AS successCount,
  CAST(sumIf(error IS NOT NULL AND failure_reason = 2, 1) AS UInt64) AS errorCount,
  avg(component_score) AS avgScore
FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE}
WHERE created_at >= '${chLit(params.start)}' AND created_at <= '${chLit(params.end)}'
  AND is_redteam = 0
  AND metric_key != ''
  ${passFilter}
  ${traceScopeFilter(scope)}
  ${optionalAppProjectFilter(params)}
GROUP BY metric_key
ORDER BY metric_key
`.trim();
}
/** Evaluated metric components (pass + fail); not top-level grading_pass row counts. */
function totalEvaluationsFromComponentCountsSql(alias = 'e') {
    return `(
    ifNull(${alias}.functionalComponentPassCount, 0) +
    ifNull(${alias}.functionalComponentFailCount, 0) +
    ifNull(${alias}.securityComponentPassCount, 0) +
    ifNull(${alias}.securityComponentFailCount, 0)
  )`;
}
/** Denormalized session-list eval aggregation (GROUP BY session_id). */
function buildSessionListEvalCteSqlDenorm(sessionIdFilterSql, applicationIdsInClause) {
    return `
SELECT
  session_id AS sessionId,
  countIf(is_redteam = 0 AND grading_pass = 1) AS functionalPassCount,
  countIf(is_redteam = 0 AND grading_pass = 0) AS functionalFailCount,
  countIf(is_redteam = 1 AND grading_pass = 1) AS securityPassCount,
  countIf(is_redteam = 1 AND grading_pass = 0) AS securityFailCount,
  sumIf(component_pass_count, is_redteam = 0) AS functionalComponentPassCount,
  sumIf(component_fail_count, is_redteam = 0) AS functionalComponentFailCount,
  sumIf(component_pass_count, is_redteam = 1) AS securityComponentPassCount,
  sumIf(component_fail_count, is_redteam = 1) AS securityComponentFailCount
FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
WHERE session_id IN (${sessionIdFilterSql})
  AND application_id IN (${applicationIdsInClause})
GROUP BY session_id
`.trim();
}
/** Trace IDs per denorm row for equi-join (ClickHouse cannot join on has(trace_ids, id)). */
const TRACE_LOOKUP_ARRAY_EXPR = `if(
      length(trace_ids) > 0,
      trace_ids,
      if(
        trace_id NOT IN ('', 'null') AND trace_id IS NOT NULL,
        [trace_id],
        emptyArrayString()
      )
    )`;
function greatestComponentCountSql(analyticsExpr, componentsAlias, legacyAlias, field) {
    return `greatest(
    ${analyticsExpr},
    ifNull(max(${componentsAlias}.${field}), 0),
    ifNull(max(${legacyAlias}.${field}), 0)
  )`;
}
/** Denormalized trace-list eval aggregation: flatten trace_ids, then join on trace_lookup_id. */
function buildTraceListEvalCteSqlDenorm(params) {
    return `
SELECT
  t.id AS traceId,
  countIf(a.is_redteam = 0 AND a.grading_pass = 1) AS functionalPassCount,
  countIf(a.is_redteam = 0 AND a.grading_pass = 0) AS functionalFailCount,
  countIf(a.is_redteam = 1 AND a.grading_pass = 1) AS securityPassCount,
  countIf(a.is_redteam = 1 AND a.grading_pass = 0) AS securityFailCount,
  ${greatestComponentCountSql('sumIf(a.component_pass_count, a.is_redteam = 0)', 'cc', 'leg', 'functionalComponentPassCount')} AS functionalComponentPassCount,
  ${greatestComponentCountSql('sumIf(a.component_fail_count, a.is_redteam = 0)', 'cc', 'leg', 'functionalComponentFailCount')} AS functionalComponentFailCount,
  ${greatestComponentCountSql('sumIf(a.component_pass_count, a.is_redteam = 1)', 'cc', 'leg', 'securityComponentPassCount')} AS securityComponentPassCount,
  ${greatestComponentCountSql('sumIf(a.component_fail_count, a.is_redteam = 1)', 'cc', 'leg', 'securityComponentFailCount')} AS securityComponentFailCount
FROM traces AS t
LEFT JOIN (
  SELECT
    trace_lookup_id,
    is_redteam,
    grading_pass,
    component_pass_count,
    component_fail_count
  FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
  ARRAY JOIN ${TRACE_LOOKUP_ARRAY_EXPR} AS trace_lookup_id
  WHERE trace_lookup_id NOT IN ('', 'null')
    ${optionalAppProjectFilter(params)}
) AS a ON a.trace_lookup_id = t.id
LEFT JOIN (
  SELECT
    trace_lookup_id,
    countIf(component_pass = 1 AND is_redteam = 0) AS functionalComponentPassCount,
    countIf(component_pass = 0 AND is_redteam = 0 AND failure_reason != 2) AS functionalComponentFailCount,
    countIf(component_pass = 1 AND is_redteam = 1) AS securityComponentPassCount,
    countIf(component_pass = 0 AND is_redteam = 1 AND failure_reason != 2) AS securityComponentFailCount
  FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE}
  ARRAY JOIN ${TRACE_LOOKUP_ARRAY_EXPR} AS trace_lookup_id
  WHERE trace_lookup_id NOT IN ('', 'null')
    ${optionalAppProjectFilter(params)}
  GROUP BY trace_lookup_id
) AS cc ON cc.trace_lookup_id = t.id
LEFT JOIN (
  SELECT
    traceId,
    sumIf(arrayCount(x -> JSONExtractBool(x, 'pass'), component_objects), is_redteam = 0) AS functionalComponentPassCount,
    sumIf(arrayCount(x -> NOT JSONExtractBool(x, 'pass'), component_objects), is_redteam = 0) AS functionalComponentFailCount,
    sumIf(arrayCount(x -> JSONExtractBool(x, 'pass'), component_objects), is_redteam = 1) AS securityComponentPassCount,
    sumIf(
      arrayCount(x -> NOT JSONExtractBool(x, 'pass') OR failure_reason = 1, component_objects),
      is_redteam = 1
    ) AS securityComponentFailCount
  FROM (
    SELECT
      trace_id AS traceId,
      is_redteam,
      coalesce(
        JSONExtract(CAST(grading_result AS String), 'componentResults', 'Array(String)'),
        []
      ) AS component_objects,
      failure_reason
    FROM ${EVAL_RESULTS_TABLE}
    WHERE grading_result IS NOT NULL
      AND trace_id IN (SELECT id FROM traces)
      ${optionalAppProjectFilter(params)}
  ) AS e
  GROUP BY traceId
) AS leg ON leg.traceId = t.id
GROUP BY t.id
`.trim();
}
function buildSecurityOverviewSqlDenorm(whereCore) {
    return `
SELECT
  count(eval_id) AS total,
  countIf(grading_pass = 1) AS successes,
  countIf(failure_reason = 2) AS errors,
  countIf(grading_pass = 0 AND failure_reason != 2) AS failures,
  uniqExact(trace_id) AS total_security_runs,
  arrayFilter(x -> x != '', groupUniqArray(plugin_id)) AS plugins
FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
WHERE ${whereCore}
AND trace_id IS NOT NULL AND trace_id NOT IN ('', 'null')
`.trim();
}
/** Trace-level eval pass/fail counts (functional); min(grading_pass) per trace. */
function buildObserveEvalStatsSqlDenorm(params) {
    return `
SELECT
  uniqExact(trace_id) AS tracesEvaluated,
  countIf(min_pass = 1) AS evaluationPassed,
  countIf(min_pass = 0) AS evaluationsFailed
FROM (
  SELECT
    trace_id,
    min(grading_pass) AS min_pass
  FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
  WHERE project_id = '${chLit(params.projectId)}'
    AND created_at >= '${chLit(params.start)}'
    AND created_at <= '${chLit(params.end)}'
    AND trace_id IS NOT NULL AND trace_id != '' AND trace_id != 'null'
    AND is_redteam = 0
    ${params.appFilterEval}
  GROUP BY trace_id
)
`.trim();
}
function buildObserveEvalStatsFilteredSqlDenorm(params) {
    const metricPart = params.metricIdsList.length > 0
        ? `
    SELECT
      trace_id,
      CAST(component_pass, 'UInt64') AS passed,
      CAST(component_pass = 0, 'UInt64') AS failed
    FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE}
    WHERE project_id = '${chLit(params.projectId)}'
      AND created_at >= '${chLit(params.start)}'
      AND created_at <= '${chLit(params.end)}'
      AND trace_id IS NOT NULL AND trace_id != '' AND trace_id != 'null'
      AND is_redteam = 0
      AND (
        metric_key IN (${params.metricIdsList})
        OR assertion_type IN (${params.metricIdsList})
        OR assertion_display_label IN (${params.metricIdsList})
      )
      ${params.appFilterEval}`
        : '';
    const pluginPart = params.pluginIdsList.length > 0
        ? `
    SELECT
      trace_id,
      CAST(grading_pass, 'UInt64') AS passed,
      CAST(grading_pass = 0, 'UInt64') AS failed
    FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
    WHERE project_id = '${chLit(params.projectId)}'
      AND created_at >= '${chLit(params.start)}'
      AND created_at <= '${chLit(params.end)}'
      AND trace_id IS NOT NULL AND trace_id != '' AND trace_id != 'null'
      AND is_redteam = 1
      AND plugin_id IN (${params.pluginIdsList})
      ${params.appFilterEval}`
        : '';
    const union = metricPart && pluginPart ? ' UNION ALL ' : '';
    return `
SELECT
  uniqExact(trace_id) AS tracesEvaluated,
  sum(passed) AS evaluationPassed,
  sum(failed) AS evaluationsFailed
FROM (
  ${metricPart}${union}${pluginPart}
)
`.trim();
}
/** Maps analytics row to legacy total-records status_priority (0=success, 1=error, 2=fail). */
exports.ANALYTICS_STATUS_PRIORITY_EXPR = `max(
        if(grading_pass = 1, 0,
          if(grading_pass = 0 AND failure_reason != 2, 2,
            if(error IS NOT NULL AND failure_reason = 2, 1, -1)
          )
        )
      )`;
function buildTotalRecordsSqlDenorm(params) {
    const { start, end, projectId, applicationId, timeGrouping, timeFieldName } = params;
    const scope = `created_at BETWEEN '${chLit(start)}' AND '${chLit(end)}'
      AND is_redteam = 0
      AND application_id = '${chLit(applicationId)}'
      AND project_id = '${chLit(projectId)}'`;
    return `
WITH traces_time_counts AS (
  SELECT
    ${timeFieldName},
    countIf(status_priority = 0) AS time_success,
    countIf(status_priority = 2) AS time_failure,
    countIf(status_priority = 1) AS time_error
  FROM (
    SELECT
      ${timeGrouping} AS ${timeFieldName},
      trace_id,
      ${exports.ANALYTICS_STATUS_PRIORITY_EXPR} AS status_priority
    FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
    WHERE ${scope}
      AND trace_id NOT IN ('', 'null') AND trace_id IS NOT NULL
    GROUP BY ${timeFieldName}, trace_id
  )
  GROUP BY ${timeFieldName}
),
traces_totals AS (
  SELECT
    count() AS total_requests,
    countIf(status_priority = 0) AS total_success,
    countIf(status_priority = 2) AS total_failures,
    countIf(status_priority = 1) AS total_errors
  FROM (
    SELECT
      trace_id,
      ${exports.ANALYTICS_STATUS_PRIORITY_EXPR} AS status_priority
    FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
    WHERE ${scope}
      AND trace_id NOT IN ('', 'null') AND trace_id IS NOT NULL
    GROUP BY trace_id
  )
),
sessions_time_counts AS (
  SELECT
    ${timeFieldName},
    countIf(status_priority = 0) AS time_success,
    countIf(status_priority = 2) AS time_failure,
    countIf(status_priority = 1) AS time_error
  FROM (
    SELECT
      ${timeGrouping} AS ${timeFieldName},
      session_id,
      ${exports.ANALYTICS_STATUS_PRIORITY_EXPR} AS status_priority
    FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
    WHERE ${scope}
      AND session_id NOT IN ('', 'null') AND session_id IS NOT NULL
    GROUP BY ${timeFieldName}, session_id
  )
  GROUP BY ${timeFieldName}
),
sessions_totals AS (
  SELECT
    count() AS total_requests,
    countIf(status_priority = 0) AS total_success,
    countIf(status_priority = 2) AS total_failures,
    countIf(status_priority = 1) AS total_errors
  FROM (
    SELECT
      session_id,
      ${exports.ANALYTICS_STATUS_PRIORITY_EXPR} AS status_priority
    FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE}
    WHERE ${scope}
      AND session_id NOT IN ('', 'null') AND session_id IS NOT NULL
    GROUP BY session_id
  )
),
traces_chart AS (
  SELECT arrayMap(
    (time, s, f, e) -> [
      tuple(time, s, 'Success'),
      tuple(time, f, 'Fail'),
      tuple(time, e, 'Error')
    ],
    groupArray(${timeFieldName}),
    groupArray(time_success),
    groupArray(time_failure),
    groupArray(time_error)
  ) AS chart_data
  FROM traces_time_counts
),
sessions_chart AS (
  SELECT arrayMap(
    (time, s, f, e) -> [
      tuple(time, s, 'Success'),
      tuple(time, f, 'Fail'),
      tuple(time, e, 'Error')
    ],
    groupArray(${timeFieldName}),
    groupArray(time_success),
    groupArray(time_failure),
    groupArray(time_error)
  ) AS chart_data
  FROM sessions_time_counts
)
SELECT
  t.total_requests     AS traces_total_requests,
  t.total_success      AS traces_total_success,
  t.total_failures     AS traces_total_failures,
  t.total_errors       AS traces_total_errors,
  tc.chart_data        AS traces_chart_data,
  s.total_requests     AS sessions_total_requests,
  s.total_success      AS sessions_total_success,
  s.total_failures     AS sessions_total_failures,
  s.total_errors       AS sessions_total_errors,
  sc.chart_data        AS sessions_chart_data
FROM traces_totals t
CROSS JOIN sessions_totals s
CROSS JOIN traces_chart tc
CROSS JOIN sessions_chart sc
LIMIT 1
`.trim();
}
/** Functional metrics and security plugins (matches legacy eval_results scope). */
function aiReliabilityComponentFilter(alias) {
    const p = alias ? `${alias}.` : '';
    return `AND (${p}metric_key != '' OR ${p}plugin_id != '')`;
}
function buildAiReliabilitySqlDenorm(params, bucketConfig) {
    const appFilter = optionalAppProjectFilter(params);
    const scope = traceOrSessionScopeFilter();
    return `
WITH
  toDateTime('${chLit(params.rangeStart)}') AS range_start,
  toDateTime('${chLit(params.rangeEnd)}') AS range_end,
  ${bucketConfig.rangeStartExpression} AS fill_from,
  ${bucketConfig.rangeEndExpression} AS fill_to,
  (
    SELECT argMax(raw_reliability_score, bucket_start)
    FROM (
      SELECT
        bucket_start,
        if(sum(row_total_cases) > 0, round(sum(row_pass_cases) / sum(row_total_cases), 4), NULL) AS raw_reliability_score
      FROM (
        SELECT
          ${bucketConfig.bucketExpression} AS bucket_start,
          countIf(component_pass = 1) AS row_pass_cases,
          count() AS row_total_cases
        FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE}
        WHERE created_at < range_start
          ${aiReliabilityComponentFilter()}
          ${scope}
          ${appFilter}
        GROUP BY bucket_start, eval_result_id
      )
      WHERE row_total_cases > 0
      GROUP BY bucket_start
    )
  ) AS seed_reliability_score
SELECT
  formatDateTime(bucket_start, '%Y-%m-%d %H:%i:%s') AS timestamp,
  toInt64(pass_cases) AS pass_cases,
  toInt64(total_cases) AS total_cases,
  toFloat64(
    ifNull(
      round(
        last_value(raw_reliability_score) IGNORE NULLS OVER (
          ORDER BY bucket_start ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        ),
        4
      ),
      ifNull(seed_reliability_score, 0)
    )
  ) AS reliability_score
FROM (
  SELECT
    bucket_start,
    sum(row_pass_cases) AS pass_cases,
    sum(row_total_cases) AS total_cases,
    if(sum(row_total_cases) > 0, round(sum(row_pass_cases) / sum(row_total_cases), 4), NULL) AS raw_reliability_score
  FROM (
    SELECT
      ${bucketConfig.bucketExpression} AS bucket_start,
      countIf(component_pass = 1) AS row_pass_cases,
      count() AS row_total_cases
    FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE}
    WHERE created_at >= range_start
      AND created_at <= range_end
      ${aiReliabilityComponentFilter()}
      ${scope}
      ${appFilter}
    GROUP BY bucket_start, eval_result_id
  )
  GROUP BY bucket_start
  HAVING sum(row_total_cases) > 0
  ORDER BY bucket_start
  WITH FILL
    FROM fill_from
    TO fill_to
    STEP ${bucketConfig.fillStep}
)
ORDER BY timestamp ASC
`.trim();
}
//# sourceMappingURL=queryAdapter.js.map