Ulugbek Abdullaev be8a7fa8f8 Make adaptive aggressiveness configurable and update to new algorithm (#3437)
* feat(inlineEdits): make user happiness score algorithm configurable

Add UserHappinessScoreConfiguration interface and experiment-based config
to allow tuning the happiness score calculation via experiments:

- Add configurable score weights (acceptedScore, rejectedScore)
- Add configurable thresholds (highThreshold, mediumThreshold)
- Add InlineEditsUserHappinessScoreConfigurationString config key
- Load configuration from experiment service with JSON validation

The algorithm behavior remains unchanged with default values matching
the original hardcoded implementation (accepted=1, rejected=0,
highThreshold=0.7, mediumThreshold=0.4).

* feat(inlineEdits): add ignored action tracking to happiness score

Add support for tracking when users ignore (neither accept nor reject)
inline edit suggestions:

- Add 'ignored' action type alongside 'accepted' and 'rejected'
- Add handleIgnored() method to UserInteractionMonitor, XtabProvider,
  and IStatelessNextEditProvider interface
- Add configurable ignoredScore (default: 0.9, near-accept)
- Skip ignored actions in debounce time calculation

This allows the happiness score algorithm to account for suggestions
that were shown but neither explicitly accepted nor rejected.

* feat(inlineEdits): update happiness score to v2 algorithm

Implement enhanced happiness score calculation with improved handling
of ignored/not-accepted actions:

Algorithm changes:
- Add ignored action limiting via window expansion to prevent score
  dilution from long sequences of ignored suggestions
- Add normalized scoring (0-1 range based on accept/reject weights)
- Add configurable options: includeIgnored, ignoredLimit,
  limitConsecutiveIgnored, limitTotalIgnored

Default value changes (tuned via experimentation):
- rejectedScore: 0 -> 0.2 (partial credit for explicit rejection)
- ignoredScore: 0.9 -> 0.5 (neutral treatment for ignored)
- highThreshold: 0.7 -> 0.6 (slightly easier to reach high aggressiveness)

New defaults enable total-ignored limiting (max 5 ignored actions in
the 10-action window) which allows the algorithm to look further back
in history to find meaningful accept/reject signals.

* Rename adaptive aggressiveness configuration

* feat(tests): add user happiness score tests to ensure new configurable algorithm behaves like original

* Keep more items than MAX_INTERACTIONS_CONSIDERED to account for dynamic window.

* Record ignore events to user interaction monitor

* Keep old behavior for timing; use a separate array to track events for aggressiveness level, including "ignored" events

* Only log events to interaction monitor if edit was shown and not superseded

* Add unit tests for happiness calculation and history logging

* Make default config equivalent to the original formula

* Make the unit test check the actual v2 implementation

* Fix test

* Log aggressiveness level and happiness score to XTabProvider log context

* Remove local files

* Remove extra line

* Doc

* Move validator to xtabPromptOptions

* Fix typo in configuration name

* Fix fallback to 0.5 calculation to use the correct denominator

* Catch and log validation errors, fallback to default

* Revert accidental change to default adaptive mode settings. Add validator for configured values. Remove default values from comments to avoid redundancy.

* Move lint options parsing function next to its validator

* Restore vscode settings

* Added a member variable to track if the last edit was shown instead of passing wasShown. Tested that only one suggestion is shown at a time, even with side-by-side editors of the same or different file (clicking away from the editor ignores the suggestion)

* Fix test

* use an enum instead of union of strings

* do not use `as any`

* fix reversed args

* migrate to using ActionKind enum and use TestLogService

---------

Co-authored-by: Ben Steenhoek <bensteenhoek@microsoft.com>
2026-02-04 11:29:35 +00:00
S
Description
Languages
TypeScript 76%
jsonc 19.6%
CSS 1.3%
JavaScript 0.7%
C 0.7%
Other 1.4%