ReLocateComment calls the LLM to regenerate a precise existing_code snippet when text-based matching fails, then retries ResolveComment with the new snippet. messages comes from BuildReLocationMessages; the caller has already recorded it in the session, so only (success, response) are returned here.
( ctx context.Context, cm *model.LlmComment, d *model.Diff, client llm.LLMClient, messages []llm.Message, modelName string, maxTokens int, )
| 47 | // recorded it in the session, so only (success, response) are returned here. |
| 48 | // Response is nil when the request failed. |
| 49 | func ReLocateComment( |
| 50 | ctx context.Context, |
| 51 | cm *model.LlmComment, |
| 52 | d *model.Diff, |
| 53 | client llm.LLMClient, |
| 54 | messages []llm.Message, |
| 55 | modelName string, |
| 56 | maxTokens int, |
| 57 | ) (bool, *llm.ChatResponse) { |
| 58 | if len(messages) == 0 { |
| 59 | return false, nil |
| 60 | } |
| 61 | |
| 62 | startTime := time.Now() |
| 63 | _, llmSpan := telemetry.StartLLMSpan(ctx, modelName) |
| 64 | resp, err := client.CompletionsWithCtx(ctx, llm.ChatRequest{ |
| 65 | Model: modelName, |
| 66 | Messages: messages, |
| 67 | MaxTokens: maxTokens, |
| 68 | }) |
| 69 | duration := time.Since(startTime) |
| 70 | if err != nil { |
| 71 | telemetry.RecordLLMResult(llmSpan, duration, 0, err) |
| 72 | llmSpan.End() |
| 73 | fmt.Fprintf(stdout.Writer(), "[ocr] Re-location LLM call failed for %s: %v\n", cm.Path, err) |
| 74 | return false, nil |
| 75 | } |
| 76 | var totalTokens int64 |
| 77 | if resp.Usage != nil { |
| 78 | totalTokens = resp.Usage.TotalTokens |
| 79 | } |
| 80 | telemetry.RecordLLMResult(llmSpan, duration, totalTokens, nil) |
| 81 | llmSpan.End() |
| 82 | |
| 83 | code := extractCodeBlock(resp.Content()) |
| 84 | if code == "" { |
| 85 | return false, resp |
| 86 | } |
| 87 | |
| 88 | original := cm.ExistingCode |
| 89 | cm.ExistingCode = code |
| 90 | if ResolveComment(cm, d) { |
| 91 | return true, resp |
| 92 | } |
| 93 | cm.ExistingCode = original |
| 94 | return false, resp |
| 95 | } |
| 96 | |
| 97 | // extractCodeBlock extracts the content of the first fenced code block from text. |
| 98 | // Returns empty string if no code block is found. |