Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Langfuse Langfuse CommentFilterService

From Leeroopedia
Knowledge Sources
Domains Filtering, Comments, Data Access
Last Updated 2026-02-14 00:00 GMT

Overview

The commentFilterService processes comment-based filter conditions (comment count and comment content) from the UI filter state and converts them into object ID inclusion/exclusion filters compatible with ClickHouse queries.

Description

This module bridges the gap between PostgreSQL-stored comments and ClickHouse-stored traces/observations/sessions. Since comments live in PostgreSQL and trace data lives in ClickHouse, filtering by comment properties requires a two-step approach: first query PostgreSQL for matching object IDs, then inject those IDs into the ClickHouse filter state.

The primary export is applyCommentFilters, which:

  1. Extracts commentCount and commentContent filters from the filter state.
  2. If no comment filters are present, returns the original filter state unchanged.
  3. For comment count filters, determines whether the filter range includes zero:
    • Includes zero (e.g., >= 0, <= 5): Uses exclusion logic -- finds objects that EXCEED the upper bound and adds a "none of" filter to exclude them, since objects with zero comments are not in the comments table.
    • Excludes zero (e.g., >= 1, > 0): Uses standard inclusion logic -- finds matching object IDs and adds an "any of" filter.
  4. For comment content filters, queries for objects with matching comment text.
  5. When both count and content filters are present, intersects the results (AND logic).
  6. Validates that the number of matching object IDs does not exceed COMMENT_FILTER_THRESHOLD (50,000) to protect ClickHouse from excessively large IN clauses.

The function returns three values:

  • filterState -- the updated filter state with comment filters replaced by ID-based filters
  • hasNoMatches -- boolean indicating the caller should return an empty result
  • matchingIds -- the raw matching IDs (useful for intersection with other ID lists, e.g., metrics endpoint)

Usage

Use this service when you need to:

  • Filter traces, sessions, or observations by comment count or comment content in any table listing endpoint.
  • Convert user-facing comment filter UI conditions into database-executable filters.
  • Handle the zero-comment edge case where objects without comments need to be included in results.

Code Reference

Source Location

Signature

export const COMMENT_FILTER_THRESHOLD = 50000;

export function validateObjectIdCount(
  objectIds: string[],
  objectType: CommentObjectType,
): void;

export async function applyCommentFilters(params: {
  filterState: z.infer<typeof singleFilter>[];
  prisma: PrismaClient;
  projectId: string;
  objectType: CommentObjectType;
  idColumn?: string;
}): Promise<{
  filterState: z.infer<typeof singleFilter>[];
  hasNoMatches: boolean;
  matchingIds: string[] | null;
}>;

Import

import { applyCommentFilters, COMMENT_FILTER_THRESHOLD } from "@langfuse/shared/src/server/services/commentFilterService";

I/O Contract

Inputs

Name Type Required Description
filterState singleFilter[] Yes The current filter state from the UI, potentially containing commentCount and commentContent filters
prisma PrismaClient Yes Prisma client instance for querying comments in PostgreSQL
projectId string Yes The project ID scoping the comment queries
objectType CommentObjectType Yes The type of object being filtered (e.g., "TRACE", "SESSION", "OBSERVATION")
idColumn string No The column name for object IDs in the resulting filter (defaults to "id")

Outputs

Name Type Description
filterState singleFilter[] Updated filter state with comment filters replaced by stringOptions ID filters
hasNoMatches boolean true if comment filters matched zero objects (caller should return empty result)
matchingIds string[] or null The matching object IDs, or null if no comment filters were present

Usage Examples

import { applyCommentFilters } from "@langfuse/shared/src/server/services/commentFilterService";

// In a tRPC endpoint for listing traces
const { filterState, hasNoMatches, matchingIds } = await applyCommentFilters({
  filterState: input.filter ?? [],
  prisma: ctx.prisma,
  projectId: ctx.session.projectId,
  objectType: "TRACE",
});

if (hasNoMatches) {
  return { traces: [], totalCount: 0 };
}

// Use the updated filterState in the ClickHouse query
const traces = await getTracesTable({
  projectId: ctx.session.projectId,
  filter: filterState,
  orderBy: input.orderBy,
  limit: input.limit,
  page: input.page,
});

// For metrics endpoint, intersect with another ID list
if (matchingIds) {
  const filteredMetricIds = metricTraceIds.filter(
    (id) => matchingIds.includes(id)
  );
}

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment