Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 15, 2026

Fixes microsoft/vscode#287573

The conversation.repetition.detected event was not firing for cancelled requests, missing cases where thought looping leads to user cancellation.

Changes

Added checkRepetitionInDeltas method

  • Reconstructs text from response deltas collected before cancellation
  • Approximates tokens via whitespace splitting (actual token array unavailable until completion)
  • Applies existing anomaly detection: isRepetitive() for token patterns, calculateLineRepetitionStats() for line repetition
  • Sends same telemetry events with finishReason: 'canceled'

Updated processCanceledResponse

  • Accepts streamRecorder and telemetryProperties parameters
  • Invokes repetition check before returning cancelled response

Limitations

Enhanced telemetry for cancelled requests lacks RequestId object fields (completionId, deploymentId, serverExperiments) since only the headerRequestId string is available. Token approximation is less precise than actual tokenization but sufficient for detecting obvious repetition patterns.

// Before: repetition only checked in completed responses
if (!this.isRepetitive(chatCompletion, baseTelemetry?.properties)) {
    completions.push(chatCompletion);
}

// After: also checked in cancelled responses
case FetchResponseKind.Canceled:
    return this.processCanceledResponse(response, ourRequestId, streamRecorder, telemetryProperties);
Original prompt

This section details on the original issue you should resolve

<issue_title>Expand coverage of conversation.repetition.detected to cancelled requests</issue_title>
<issue_description>

We currently have the conversation.repetition.detected event that looks for repeating lines. It appears from the codeand my own local testing that we do not fire this event when the request was cancelled. I believe this is a major gap because true thought repetition within a request would probably lead to the user intervening and cancelling before it completes most of the time. We would like to use this metric to track occurrence of thought looping within a single request. We may also be able to use other tools in CAPI to detect this, but if it is a relatively easy change, I think it could be worth looking at this from the client side as well.

FYI @isidorn , @lramos15 </issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 5 commits January 15, 2026 19:32
- Add checkRepetitionInDeltas method to analyze partial responses
- Modify processCanceledResponse to check for repetition before returning
- Send conversation.repetition.detected telemetry for both token and line repetition
- Mark finishReason as 'canceled' to distinguish from completed requests

Co-authored-by: vijayupadya <[email protected]>
- Filter out undefined/null delta.text values before joining
- Add requestId to telemetry properties for consistency with completed requests
- Clarify comment about token approximation

Co-authored-by: vijayupadya <[email protected]>
- Filter out null, undefined, and empty text values from deltas
- Remove manual requestId assignment for enhanced telemetry (not needed)
- Add clarifying comment about RequestId object unavailability

Co-authored-by: vijayupadya <[email protected]>
- Document key differences from completed request handling
- Explain token approximation limitations
- Document missing telemetry fields for cancelled requests
- Clarify finishReason usage

Co-authored-by: vijayupadya <[email protected]>
Copilot AI changed the title [WIP] Expand coverage of conversation.repetition.detected to cancelled requests Expand conversation.repetition.detected telemetry to cancelled requests Jan 15, 2026
Copilot AI requested a review from vijayupadya January 15, 2026 19:42
@vijayupadya vijayupadya marked this pull request as ready for review January 16, 2026 21:02
Copilot AI review requested due to automatic review settings January 16, 2026 21:02
@vs-code-engineering vs-code-engineering bot added this to the January 2026 milestone Jan 16, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the conversation.repetition.detected telemetry event to fire for cancelled requests, addressing a gap where thought looping that leads to user cancellation was not being tracked.

Changes:

  • Added checkRepetitionInDeltas method to detect repetition patterns in partial responses from cancelled requests
  • Updated processCanceledResponse to accept additional parameters and invoke repetition checking before returning
  • Modified the cancelled request handling flow to pass streamRecorder and telemetryProperties for repetition detection

telemetryProperties?: TelemetryProperties
): void {
// Reconstruct the text content from deltas (filter out null, undefined, and empty text values)
const textContent = deltas.filter(delta => delta.text != null && delta.text !== '').map(delta => delta.text).join('');
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filtering condition delta.text != null && delta.text !== '' could be simplified using a more idiomatic approach. Consider extracting this to a named function or using a clearer filter condition like delta.text?.length > 0 which combines null/undefined checking with empty string checking.

Suggested change
const textContent = deltas.filter(delta => delta.text != null && delta.text !== '').map(delta => delta.text).join('');
const textContent = deltas.filter(delta => delta.text?.length > 0).map(delta => delta.text).join('');

Copilot uses AI. Check for mistakes.

// For cancelled requests, we don't have the actual token array (only available in ChatCompletion),
// so we approximate by splitting text content on whitespace. This is less precise than actual
// tokenization but sufficient for detecting obvious repetition patterns.
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the comment above explains that this is an approximation, it would be helpful to add a brief inline comment noting that this tokenization approach will differ from actual LLM tokenization (which may split on different boundaries). This would help future maintainers understand why results might differ between completed and cancelled requests.

Suggested change
// tokenization but sufficient for detecting obvious repetition patterns.
// tokenization but sufficient for detecting obvious repetition patterns.
// Note: This whitespace-based split does not match the model's real tokenization, so
// repetition metrics here may differ slightly from those computed for completed responses.

Copilot uses AI. Check for mistakes.
@vijayupadya vijayupadya enabled auto-merge January 16, 2026 21:58
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.

Expand coverage of conversation.repetition.detected to cancelled requests

2 participants