lsp: budget diagnostics to cap token noise
Summary
- Cap LSP diagnostics to reduce token/latency overhead while keeping high-signal errors
- Limits: 50 diags per file, 8 KB total payload, messages trimmed to 200 chars, deduped; summary when truncated
- Tests: diagnostics budget caps + preserves highest-severity; typecheck
Benchmarks
- Synthetic (300 noisy diags + 5 errors): 70,742 chars → 8,116 chars (~88.5% reduction); noisy kept 33 entries (incl. top severity + summary); clean kept 5/5.
- Live OpenRouter API agent(gpt-4o-mini) end-to-end:
- Prompt: raw 70,742 chars → budgeted 8,116 chars
- Tokens/cost: raw prompt 13,109 / completion 1,396 / total 14,505; budgeted prompt 1,619 / completion 493 / total 2,112 (≈85% fewer total tokens). Cost: /bin/zsh.00188235 → /bin/zsh.00046185 (~75% cheaper)
- Latency: raw ~25.2s → budgeted ~9.4s (≈2.7× faster)
- Response quality: top severity items preserved; budgeted output still lists the real errors (err-0..err-4) plus top warn-* entries.
Tests
- bun test packages/opencode/test/lsp/diagnostics-budget.test.ts
- bun test packages/opencode/test/lsp/diagnostics-budget-agent-signal.test.ts
- bun run typecheck
2 files in here (around 60 lines) are the harness + testing suite which can be removed if this is wanted but they show clarity to how it is used and can be used
This is also in coherence with the Biome LSP additions and would not affect each-other negatively
diffray code review
Free public review - Want AI code reviews on your PRs? Check out diffray.ai
Summary
Validated 6 issues: 4 kept (2 medium quality concerns, 2 architecture suggestions), 2 filtered (low-value magic number suggestions)
Issues Found: 4
See 2 individual line comment(s) for details.
Full issue list (click to expand)
🟡 MEDIUM - Using 'any' type instead of specific types
File: packages/opencode/src/lsp/index.ts:393-394
Category: quality
Description: TypeScript 'any' disables type checking and should be avoided
Suggestion: Define a proper type for the LSP response, such as type WorkspaceSymbolResponse = Array<LSP.Symbol & { kind: number }> or use unknown with type guards
Confidence: 78%
Rule: ts_any_type_usage
🟡 MEDIUM - Missing explicit return type on function
File: packages/opencode/src/lsp/index.ts:273
Category: quality
Description: Exported function doesn't specify return type
Suggestion: Add explicit return type: export function budgetDiagnostics(input: Record<string, LSPClient.Diagnostic[]>): Record<string, LSPClient.Diagnostic[]>
Confidence: 72%
Rule: ts_missing_return_type
🔵 LOW - Magic number without named constant
File: packages/opencode/src/lsp/index.ts:280-312
Category: quality
Description: Numeric literal '3' used for severity default without explanation
Suggestion: Extract to named constant: const DEFAULT_SEVERITY = 3; // INFO level and use in comparisons. Severity mapping already exists in lines 421-426 but not centralized.
Confidence: 62%
Rule: quality_magic_numbers
🟡 MEDIUM - Avoid TypeScript namespaces in modern code
File: packages/opencode/src/lsp/index.ts:11-435
Category: quality
Description: Uses TypeScript namespace pattern (export namespace LSP) instead of ES modules. Namespaces are a legacy pattern.
Suggestion: Refactor to ES modules: move exports to separate files like lsp/types.ts (Range, Symbol, DocumentSymbol), lsp/diagnostics.ts (diagnostics, budgetDiagnostics), lsp/symbols.ts (workspaceSymbol, documentSymbol). Import using standard ES module syntax.
Confidence: 68%
Rule: ts_avoid_namespace
Powered by diffray - AI Code Review