Skip to content

Search snippet formatter materializes full result set before clamping line widths #2027

Description

@Widthdom

Summary

In ExecuteSearch (Mcp/McpToolHandlers.cs:307), all SearchSnippetFormatter.ToCompactResult calls run synchronously over the full results list, clamping each snippet's line widths individually via LineWidthFormatter. For large result sets (e.g., 1000 chunk matches on a common identifier), this forces serialization of all snippets before any filtering or streaming can occur. Each result's ...(+N)... elision markers and line-width clamping are computed upfront, meaning wide queries pay quadratic memory cost. No streaming / pagination path exists to fence memory growth.

Where

  • src/CodeIndex/Mcp/McpToolHandlers.cs:307 (JsonSerializer.SerializeToNode materializes entire results)
  • src/CodeIndex/Cli/SearchSnippetFormatter.cs (ToCompactResult called per-result without streaming)
  • src/CodeIndex/Database/LineWidthFormatter.cs:15-27 (line clamp per-result, no batching or early exit)

Suggested approach

  1. Implement an IEnumerable-returning SearchSnippetFormatter.ToCompactResults that yields results lazily
  2. For MCP tools, collect results into a pre-serialized JsonArray while respecting a per-result memory budget
  3. Implement streaming JSON serialization in McpToolHandlers so each result is written to output immediately rather than accumulated
  4. Add an early_truncated field to responses when a result's line-clamp could not complete within budget
  5. Update TestSnippetFormatter to validate lazy enumeration doesn't force materialization
  6. Document this pattern for all tools returning large result sets

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions