Skip to content

Graph filtering bug fix, ai assistant response bug fix, signoz link corrected#210

Merged
robert-inkeep merged 3 commits into
mainfrom
filtering-fix
Sep 15, 2025
Merged

Graph filtering bug fix, ai assistant response bug fix, signoz link corrected#210
robert-inkeep merged 3 commits into
mainfrom
filtering-fix

Conversation

@shagun-singh-inkeep

Copy link
Copy Markdown
Collaborator

No description provided.

@vercel

vercel Bot commented Sep 15, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
agents-manage-api Ready Ready Preview Comment Sep 15, 2025 7:04pm
agents-manage-ui Ready Ready Preview Comment Sep 15, 2025 7:04pm
agents-run-api Ready Ready Preview Comment Sep 15, 2025 7:04pm
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
agents-docs Skipped Skipped Sep 15, 2025 7:04pm

@claude

claude Bot commented Sep 15, 2025

Copy link
Copy Markdown
Contributor

Claude finished @shagun-singh-inkeep's task —— View job


PR Code Review - TypeScript Staff Engineer Analysis

Completed comprehensive code review of the graph filtering fix and AI assistant response changes across 5 files.

Review Summary:

This PR implements graph-based filtering functionality and restores AI assistant response capture in the agents platform. The changes are architecturally sound but have several areas for improvement.


🔧 Technical Changes Analysis

1. Graph Filtering Implementation (agents-manage-ui)

  • signoz-link.tsx: Minor update to query parameter handling
  • traces-overview.tsx: Enhanced filtering UI with graph-specific span names and activity data
  • use-traces.ts: Added proper GraphID filtering support in hooks
  • signoz-stats.ts: Comprehensive filtering implementation with robust type safety

2. Response Capture Restoration (agents-run-api)

  • executionHandler.ts: Re-added MCPStreamHelper response capture functionality for tool contexts

Strengths

  1. Robust Type Safety: Excellent use of Zod schemas and TypeScript types in signoz-stats.ts
  2. Comprehensive Error Handling: Good error boundaries and fallback mechanisms
  3. Performance Optimization: Server-side aggregation and efficient filtering
  4. Race Condition Handling: Proper atomic operations in executionHandler.ts (lines 106-170)
  5. Memory Management: Buffer size limits and cleanup in stream helpers

⚠️ Critical Issues

1. Security & Data Validation

// signoz-stats.ts:231 - Potential XSS vulnerability
const content = first.c.length > 100 ? `${first.c.slice(0, 100)}...` : first.c;

Recommendation: Sanitize user content before truncation and storage.

2. Performance Bottlenecks

// signoz-stats.ts:248-250 - Secondary filtering after main query
if (filters?.spanName || filters?.attributes?.length) {
  stats = await this.applySpanFilters(stats, startTime, endTime, filters, projectId);
}

Issue: This causes N+1 query problem. Filters should be applied at the database level, not in memory.

3. Complex State Management

// traces-overview.tsx:73-78 - Multiple overlapping state variables
const [aiCallsByGraph, setAiCallsByGraph] = useState<Array<{ graphId: string; totalCalls: number }>([]);
const [_aiCallsLoading, setAiCallsLoading] = useState(true);
const [activityData, setActivityData] = useState<Array<{ date: string; count: number }>>([]);

Issue: State fragmentation leads to synchronization issues and complexity.


🏗️ Architectural Concerns

1. Inconsistent Filtering Pattern

The graph filtering implementation mixes client-side and server-side filtering approaches:

  • Some filters applied at query level (buildCombinedPayload)
  • Others applied post-query (applySpanFilters)

Recommendation: Standardize on server-side filtering for performance and consistency.

2. Memory Leak Potential

// executionHandler.ts:439-443 - Response capture without cleanup bounds
if (sseHelper instanceof MCPStreamHelper) {
  const captured = sseHelper.getCapturedResponse();
  response = captured.text || 'No response content';
}

Issue: Long-running executions could accumulate unbounded response data.

3. Tight Coupling in UI Components

The TracesOverview component has grown to 737 lines with multiple responsibilities:

  • Data fetching
  • State management
  • Filter management
  • UI rendering

Recommendation: Extract separate hooks and components for each concern.


🔍 Code Quality Issues

1. Magic Numbers & Configuration

// Multiple files contain hardcoded values
const TEXT_GAP_THRESHOLD = 1000; // milliseconds
const MAX_BUFFER_SIZE = 5 * 1024 * 1024; // 5MB
const MAX_ERRORS = 3;

Recommendation: Extract to configuration objects or constants files.

2. Inconsistent Error Handling

// signoz-stats.ts - Inconsistent error handling patterns
catch (e) {
  console.error('getConversationStats error:', e);
  return []; // Sometimes returns empty array
}
// vs
catch (error) {
  const errorMessage = err instanceof Error ? err.message : 'Failed to fetch';
  setError(errorMessage); // Sometimes sets error state
}

3. Type Safety Gaps

// Multiple `any` types that could be more specific
private extractSeries(resp: any, name: string): Series[]
const payload = this.buildCombinedPayload(startTime, endTime, undefined, projectId);

🚀 Performance Recommendations

1. Database Query Optimization

  • Current: Multiple separate queries then client-side joins
  • Recommended: Single query with proper JOINs and WHERE clauses

2. Caching Strategy

Consider implementing query result caching for expensive operations:

// Add caching layer for graph metadata and span names
const cacheKey = `graph-${graphId}-spans-${startTime}-${endTime}`;

3. Pagination Improvements

The current pagination is memory-intensive (loads all results then slices). Consider cursor-based pagination for large datasets.


🔧 Specific Recommendations

1. Refactor Filter Architecture

// Recommended approach - single query builder
interface FilterConfig {
  timeRange: TimeRange;
  graphId?: string;
  spanFilters?: SpanFilterOptions;
}

class QueryBuilder {
  buildFilteredQuery(config: FilterConfig): SigNozQuery {
    // Apply ALL filters at query level
  }
}

2. Extract Response Capture Logic

// Create dedicated response manager
class ResponseCaptureManager {
  constructor(private maxSize: number = 1024 * 1024) {}
  
  capture(helper: StreamHelper): Promise<CapturedResponse> {
    // Bounded capture with proper cleanup
  }
}

3. Simplify State Management

// Use reducer pattern for complex state
interface TracesState {
  filters: FilterState;
  data: DataState;
  ui: UIState;
}

const tracesReducer = (state: TracesState, action: TracesAction) => {
  // Centralized state updates
}

Overall Assessment

Functionality: The PR successfully implements graph filtering and restores response capture functionality.

Code Quality: Good type safety and error handling, but could benefit from architectural improvements.

Maintainability: Current complexity may hinder future development. Consider refactoring for cleaner separation of concerns.

Performance: Some optimization opportunities, particularly around database querying and memory management.

Security: Minor content sanitization needed for user-generated data.


📋 Action Items

  1. High Priority: Fix potential XSS vulnerability in content truncation
  2. High Priority: Optimize secondary filtering to use database queries
  3. Medium Priority: Extract component responsibilities and simplify state management
  4. Medium Priority: Add response capture size limits and cleanup
  5. Low Priority: Extract magic numbers to configuration

This is solid work that advances the platform's filtering capabilities while maintaining good engineering practices. The suggested improvements would enhance performance, security, and maintainability.

@shagun-singh-inkeep shagun-singh-inkeep changed the title Graph filtering fix and ai assistant response added back Graph filtering bug fix and ai assistant response bug fix Sep 15, 2025
@shagun-singh-inkeep shagun-singh-inkeep changed the title Graph filtering bug fix and ai assistant response bug fix Graph filtering bug fix, ai assistant response bug fix, signoz link corrected Sep 15, 2025
@vercel vercel Bot temporarily deployed to Preview – agents-docs September 15, 2025 19:01 Inactive
@claude

claude Bot commented Sep 15, 2025

Copy link
Copy Markdown
Contributor

Claude finished @shagun-singh-inkeep's task —— View job


PR Code Review - TypeScript Staff Engineer Analysis

This PR implements graph-based filtering functionality and restores AI assistant response capture across the agents platform. Here's my comprehensive technical analysis:


🔧 Changes Summary

1. Graph Filtering Implementation (agents-manage-ui)

  • Enhanced signoz-stats.ts with graph-specific filtering support
  • Updated use-traces.ts hook to pass graphId parameters
  • Minor UI and configuration adjustments in traces-overview component

2. Response Capture Restoration (agents-run-api)

  • Re-added MCPStreamHelper response capture in executionHandler.ts (lines 439-443)
  • Ensures AI assistant responses are properly captured for MCP tool contexts

Technical Strengths

  1. Robust Type Safety: Excellent use of Zod schemas and TypeScript throughout signoz-stats.ts
  2. Comprehensive Error Handling: Well-structured error boundaries with specific error types and fallbacks
  3. Performance Optimization: Server-side aggregation and efficient query building
  4. Race Condition Management: Proper atomic task creation with fallback handling in executionHandler.ts (lines 106-170)
  5. Memory Management: Response capture includes proper cleanup and bounded buffer sizes

⚠️ Critical Issues Requiring Attention

1. Security Vulnerability - Content Sanitization

// signoz-stats.ts:230 - Potential XSS risk
const content = first.c.length > 100 ? `${first.c.slice(0, 100)}...` : first.c;

Issue: User content is truncated and stored without sanitization. This could lead to XSS vulnerabilities if the content contains malicious scripts.

Recommendation: Sanitize user content before processing:

const sanitizedContent = DOMPurify.sanitize(first.c);
const content = sanitizedContent.length > 100 ? `${sanitizedContent.slice(0, 100)}...` : sanitizedContent;

2. Performance Bottleneck - N+1 Query Pattern

// signoz-stats.ts:248-250 - Secondary filtering after main query
if (filters?.spanName || filters?.attributes?.length) {
  stats = await this.applySpanFilters(stats, startTime, endTime, filters, projectId);
}

Issue: This creates an inefficient N+1 query pattern where filters are applied in memory after the initial database query.

Recommendation: Integrate filters into the primary query builder:

private buildCombinedPayload(start, end, filters, projectId, graphId) {
  // Apply ALL filters at query construction time
  const filterItems = this.buildFilterItems(filters);
  // Include in main query rather than separate filtering step
}

3. Memory Leak Potential - Unbounded Response Capture

// executionHandler.ts:439-443 - Response capture without bounds
if (sseHelper instanceof MCPStreamHelper) {
  const captured = sseHelper.getCapturedResponse();
  response = captured.text || 'No response content';
}

Issue: Long-running executions could accumulate unbounded response data in memory.

Recommendation: Implement size limits and cleanup:

class ResponseCaptureManager {
  constructor(private maxSize = 1024 * 1024) {} // 1MB limit
  
  captureWithLimits(helper: MCPStreamHelper): string {
    const captured = helper.getCapturedResponse();
    if (captured.text && captured.text.length > this.maxSize) {
      return captured.text.slice(0, this.maxSize) + '... [truncated]';
    }
    return captured.text || 'No response content';
  }
}

🏗️ Architectural Concerns

1. Inconsistent Filtering Strategy

The implementation mixes client-side and server-side filtering approaches:

  • Primary queries use server-side aggregation (buildCombinedPayload)
  • Span filters use post-query client-side filtering (applySpanFilters)

Recommendation: Standardize on server-side filtering for consistency and performance.

2. State Management Complexity

// traces-overview.tsx:73-78 - Multiple overlapping state variables
const [aiCallsByGraph, setAiCallsByGraph] = useState<Array<{ graphId: string; totalCalls: number }>([]);
const [_aiCallsLoading, setAiCallsLoading] = useState(true);
const [activityData, setActivityData] = useState<Array<{ date: string; count: number }>>([]);

Issue: Fragmented state leads to synchronization challenges.

Recommendation: Use a reducer pattern for complex state management:

interface TracesState {
  filters: FilterState;
  data: DataState; 
  ui: UIState;
}

const tracesReducer = (state: TracesState, action: TracesAction) => {
  // Centralized state updates
}

🔍 Code Quality Issues

1. Magic Numbers and Configuration

// Multiple hardcoded values throughout
const TEXT_GAP_THRESHOLD = 1000; // milliseconds  
const MAX_ERRORS = 3;
const MAX_BUFFER_SIZE = 5 * 1024 * 1024; // 5MB

Recommendation: Extract to configuration objects:

const CONFIG = {
  TIMEOUTS: { TEXT_GAP_THRESHOLD: 1000 },
  LIMITS: { MAX_ERRORS: 3, MAX_BUFFER_SIZE: 5 * 1024 * 1024 },
} as const;

2. Type Safety Gaps

// signoz-stats.ts:158 - Generic any type usage
private extractSeries(resp: any, name: string): Series[]

Recommendation: Define proper interface for SigNoz responses:

interface SigNozResponse {
  data?: {
    result?: Array<{
      queryName?: string;
      series?: Series[];
    }>;
  };
}

3. Error Handling Inconsistency

Different error handling patterns are used across files - some return empty arrays, others set error state, some log and continue.

Recommendation: Establish consistent error handling patterns:

interface ErrorHandler {
  logAndReturn<T>(error: unknown, fallback: T): T;
  logAndThrow(error: unknown): never;  
  logAndSetState(error: unknown, setter: (msg: string) => void): void;
}

📊 Performance Recommendations

  1. Database Query Optimization: Consolidate multiple queries with proper JOINs
  2. Caching Strategy: Implement query result caching for expensive graph operations
  3. Pagination Improvements: Consider cursor-based pagination for large datasets instead of offset-based
  4. Bundle Optimization: The signoz-stats.ts file is quite large (~2000 lines) - consider splitting into focused modules

🔒 Security Considerations

  1. Input Validation: The asTypedFilterValue function needs additional validation for malicious input
  2. SQL Injection: While using parameterized queries, ensure all dynamic filter construction is properly escaped
  3. Rate Limiting: Consider adding rate limiting to prevent abuse of the filtering endpoints
  4. Authentication: Verify proper authentication checks exist for all SigNoz API calls

Positive Observations

  1. Clean Architecture: Good separation of concerns between API layer, hooks, and UI components
  2. Error Resilience: Graceful degradation when SigNoz is unavailable
  3. Developer Experience: Comprehensive logging for debugging and monitoring
  4. Backward Compatibility: Changes maintain existing API contracts

🚀 Recommended Next Steps

High Priority:

  1. Fix content sanitization vulnerability (security)
  2. Optimize secondary filtering to use database queries (performance)
  3. Add response capture size limits (memory management)

Medium Priority:

  1. Refactor state management in traces-overview component
  2. Extract configuration constants
  3. Improve type safety across SigNoz interactions

Low Priority:

  1. Consider breaking down large files into focused modules
  2. Add comprehensive unit tests for new filtering functionality
  3. Document complex query construction logic

🎯 Overall Assessment

Functionality: ✅ Successfully implements graph filtering and response capture restoration
Code Quality: ⚠️ Good foundation with areas for improvement
Security: ⚠️ Requires attention to content sanitization
Performance: ⚠️ Some optimization opportunities identified
Maintainability: ✅ Generally well-structured and readable

This PR delivers solid functionality while highlighting opportunities for architectural and security improvements. The filtering feature works as intended, and the response capture restoration addresses a real user need.


@robert-inkeep robert-inkeep merged commit 7ca4066 into main Sep 15, 2025
6 of 8 checks passed
@robert-inkeep robert-inkeep deleted the filtering-fix branch September 15, 2025 19:03
amikofalvy added a commit that referenced this pull request Mar 11, 2026
Fixes XSS bypass vulnerability (CVE-2026-0540) in transitive dompurify
dependency by adding pnpm override.

Closes dependabot alerts #210, #211.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
github-merge-queue Bot pushed a commit that referenced this pull request Mar 11, 2026
* fix(security): add dompurify override >=3.3.2

Fixes XSS bypass vulnerability (CVE-2026-0540) in transitive dompurify
dependency by adding pnpm override.

Closes dependabot alerts #210, #211.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(security): add fast-xml-parser override >=5.3.8

Fixes stack overflow with preserveOrder (CVE-2026-27942) in transitive
fast-xml-parser dependency.

Closes dependabot alert #205.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(security): add serialize-javascript override >=7.0.3

Fixes RCE vulnerability via RegExp.flags and Date.prototype.toISOString()
in transitive serialize-javascript dependency (build-time only).

Closes dependabot alert #203.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(security): add svgo override >=3.3.3

Fixes DoS via entity expansion in DOCTYPE (CVE-2026-29074) in transitive
svgo dependency (build-time only).

Closes dependabot alert #212.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(security): add minimatch override >=5.1.8 — ReDoS fix (#2642)

* fix(security): add minimatch override >=5.1.8

Fixes multiple ReDoS vulnerabilities (CVE-2026-26996, CVE-2026-27903,
CVE-2026-27904) in transitive minimatch@5.x dependency.

Closes dependabot alerts #188, #199, #200.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(security): add lodash/lodash-es override >=4.17.23 — prototype pollution fix (#2643)

* fix(security): add lodash/lodash-es override >=4.17.23

Fixes prototype pollution in _.unset and _.omit (CVE-2025-13465)
in transitive lodash dependencies.

Closes dependabot alerts #120, #123.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(security): add express-rate-limit override >=8.2.2 (#2644)

Fixes IPv4-mapped IPv6 rate limit bypass (CVE-2026-30827) in transitive
express-rate-limit dependency.

Closes dependabot alert #213.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix(security): add security overrides to create-agents-template

Ensures self-hosted deployments using the template also get patched
transitive dependency versions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(security): sync overrides between root and create-agents-template

Makes pnpm.overrides identical in both package.json files so the
monorepo and self-hosted template have the same security floor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Zeeeepa pushed a commit to Zeeeepa/inkeep_agents that referenced this pull request Apr 23, 2026
GitOrigin-RevId: f4ecdec5d483ce2a6009bf2f5d9050213cbe53d6

Co-authored-by: inkeep-internal-ci[bot] <259778081+inkeep-internal-ci[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants