From 3aef4dedcfd1ad408c6cb6c06e5e731feb528a1e Mon Sep 17 00:00:00 2001 From: Kujtim Hoxha Date: Fri, 4 Apr 2025 15:03:50 +0200 Subject: Improve LSP diagnostics handling for file operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Split LSP file notification into separate functions - Add waitForLspDiagnostics function to wait for diagnostics after file changes - Move LSP diagnostics to after file operations in edit and write tools - Fix string splitting in diff generation - Reduce diagnostics timeout from 10 to 5 seconds 🤖 Generated with termai Co-Authored-By: termai --- internal/llm/tools/diagnostics.go | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'internal/llm/tools/diagnostics.go') diff --git a/internal/llm/tools/diagnostics.go b/internal/llm/tools/diagnostics.go index 3eb72eafc..ce76ae12f 100644 --- a/internal/llm/tools/diagnostics.go +++ b/internal/llm/tools/diagnostics.go @@ -53,6 +53,7 @@ func (b *diagnosticsTool) Run(ctx context.Context, call ToolCall) (ToolResponse, if params.FilePath != "" { notifyLspOpenFile(ctx, params.FilePath, lsps) + waitForLspDiagnostics(ctx, params.FilePath, lsps) } output := appendDiagnostics(params.FilePath, lsps) @@ -61,6 +62,22 @@ func (b *diagnosticsTool) Run(ctx context.Context, call ToolCall) (ToolResponse, } func notifyLspOpenFile(ctx context.Context, filePath string, lsps map[string]*lsp.Client) { + for _, client := range lsps { + // Open the file + err := client.OpenFile(ctx, filePath) + if err != nil { + // If there's an error opening the file, continue to the next client + continue + } + } +} + +// waitForLspDiagnostics opens a file in LSP clients and waits for diagnostics to be published +func waitForLspDiagnostics(ctx context.Context, filePath string, lsps map[string]*lsp.Client) { + if len(lsps) == 0 { + return + } + // Create a channel to receive diagnostic notifications diagChan := make(chan struct{}, 1) @@ -92,11 +109,18 @@ func notifyLspOpenFile(ctx context.Context, filePath string, lsps map[string]*ls // Register our temporary handler client.RegisterNotificationHandler("textDocument/publishDiagnostics", handler) - // Open the file - err := client.OpenFile(ctx, filePath) - if err != nil { - // If there's an error opening the file, continue to the next client - continue + // Notify change if the file is already open + if client.IsFileOpen(filePath) { + err := client.NotifyChange(ctx, filePath) + if err != nil { + continue + } + } else { + // Open the file if it's not already open + err := client.OpenFile(ctx, filePath) + if err != nil { + continue + } } } @@ -104,7 +128,7 @@ func notifyLspOpenFile(ctx context.Context, filePath string, lsps map[string]*ls select { case <-diagChan: // Diagnostics received - case <-time.After(10 * time.Second): + case <-time.After(5 * time.Second): // Timeout after 5 seconds - this is a fallback in case no diagnostics are published case <-ctx.Done(): // Context cancelled -- cgit v1.2.3