@codingame/monaco-vscode-workbench-service-override 37.6.1 → 38.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/common.js +2 -0
  2. package/index.js +9 -10
  3. package/package.json +10 -10
  4. package/session.js +45 -42
  5. package/vscode/src/vs/platform/agentHost/common/sessionComparisonPrompts.d.ts +1 -0
  6. package/vscode/src/vs/platform/agentHost/common/sessionComparisonPrompts.js +12 -0
  7. package/vscode/src/vs/sessions/browser/{singlePaneWorkbench.d.ts → desktopWorkbench.d.ts} +6 -5
  8. package/vscode/src/vs/sessions/browser/{singlePaneWorkbench.js → desktopWorkbench.js} +23 -25
  9. package/vscode/src/vs/sessions/browser/dockedAuxiliaryBarController.d.ts +5 -2
  10. package/vscode/src/vs/sessions/browser/dockedAuxiliaryBarController.js +41 -3
  11. package/vscode/src/vs/sessions/browser/layoutActions.js +25 -41
  12. package/vscode/src/vs/sessions/browser/mobileWorkbench.d.ts +4 -0
  13. package/vscode/src/vs/sessions/browser/mobileWorkbench.js +10 -0
  14. package/vscode/src/vs/sessions/browser/parts/chatCompositeBar.d.ts +10 -5
  15. package/vscode/src/vs/sessions/browser/parts/chatCompositeBar.js +138 -34
  16. package/vscode/src/vs/sessions/browser/parts/chatGroupDropTarget.d.ts +2 -0
  17. package/vscode/src/vs/sessions/browser/parts/chatGroupDropTarget.js +13 -5
  18. package/vscode/src/vs/sessions/browser/parts/chatGroupView.d.ts +27 -5
  19. package/vscode/src/vs/sessions/browser/parts/chatGroupView.js +129 -28
  20. package/vscode/src/vs/sessions/browser/parts/chatGroupsView.d.ts +22 -7
  21. package/vscode/src/vs/sessions/browser/parts/chatGroupsView.js +260 -21
  22. package/vscode/src/vs/sessions/browser/parts/chatHeader.d.ts +25 -0
  23. package/vscode/src/vs/sessions/browser/parts/chatHeader.js +42 -0
  24. package/vscode/src/vs/sessions/browser/parts/customViewGridPart.js +9 -1
  25. package/vscode/src/vs/sessions/browser/parts/customViewNode.js +1 -1
  26. package/vscode/src/vs/sessions/browser/parts/{singlePaneAuxiliaryBarPart.d.ts → desktopAuxiliaryBarPart.d.ts} +4 -4
  27. package/vscode/src/vs/sessions/browser/parts/desktopAuxiliaryBarPart.js +26 -0
  28. package/vscode/src/vs/sessions/browser/parts/{singlePaneEditorPart.d.ts → desktopEditorPart.d.ts} +8 -6
  29. package/vscode/src/vs/sessions/browser/parts/{singlePaneEditorPart.js → desktopEditorPart.js} +25 -5
  30. package/vscode/src/vs/sessions/browser/parts/editorPart.js +16 -4
  31. package/vscode/src/vs/sessions/browser/parts/editorParts.d.ts +1 -1
  32. package/vscode/src/vs/sessions/browser/parts/editorParts.js +7 -6
  33. package/vscode/src/vs/sessions/browser/parts/gridGap.d.ts +14 -0
  34. package/vscode/src/vs/sessions/browser/parts/gridGap.js +69 -0
  35. package/vscode/src/vs/sessions/browser/parts/media/chatCompositeBar.css +132 -4
  36. package/vscode/src/vs/sessions/browser/parts/media/chatGroupsView.css +10 -0
  37. package/vscode/src/vs/sessions/browser/parts/media/editorPart.css +46 -2
  38. package/vscode/src/vs/sessions/browser/parts/media/sessionReadOnlyBanner.css +3 -3
  39. package/vscode/src/vs/sessions/browser/parts/media/sessionView.css +45 -48
  40. package/vscode/src/vs/sessions/browser/parts/media/sessionsPart.css +15 -0
  41. package/vscode/src/vs/sessions/browser/parts/menubar.contribution.js +8 -8
  42. package/vscode/src/vs/sessions/browser/parts/mobile/mobileSessionsPart.js +1 -1
  43. package/vscode/src/vs/sessions/browser/parts/remoteHostUnavailableEmptyState.d.ts +9 -1
  44. package/vscode/src/vs/sessions/browser/parts/remoteHostUnavailableEmptyState.js +21 -3
  45. package/vscode/src/vs/sessions/browser/parts/sessionBarStyles.js +1 -1
  46. package/vscode/src/vs/sessions/browser/parts/sessionDropTarget.d.ts +4 -3
  47. package/vscode/src/vs/sessions/browser/parts/sessionDropTarget.js +29 -15
  48. package/vscode/src/vs/sessions/browser/parts/sessionGridLayout.d.ts +67 -0
  49. package/vscode/src/vs/sessions/browser/parts/sessionGridLayout.js +598 -0
  50. package/vscode/src/vs/sessions/browser/parts/sessionHeader.d.ts +11 -84
  51. package/vscode/src/vs/sessions/browser/parts/sessionHeader.js +37 -317
  52. package/vscode/src/vs/sessions/browser/parts/sessionHeaderBar.d.ts +103 -0
  53. package/vscode/src/vs/sessions/browser/parts/sessionHeaderBar.js +391 -0
  54. package/vscode/src/vs/sessions/browser/parts/sessionReadOnlyBanner.d.ts +6 -4
  55. package/vscode/src/vs/sessions/browser/parts/sessionReadOnlyBanner.js +58 -28
  56. package/vscode/src/vs/sessions/browser/parts/sessionRemoteConnection.d.ts +4 -0
  57. package/vscode/src/vs/sessions/browser/parts/sessionRemoteConnection.js +66 -23
  58. package/vscode/src/vs/sessions/browser/parts/sessionView.d.ts +24 -5
  59. package/vscode/src/vs/sessions/browser/parts/sessionView.js +143 -33
  60. package/vscode/src/vs/sessions/browser/parts/sessionsPart.d.ts +25 -19
  61. package/vscode/src/vs/sessions/browser/parts/sessionsPart.js +157 -58
  62. package/vscode/src/vs/sessions/browser/parts/sessionsParts.d.ts +12 -3
  63. package/vscode/src/vs/sessions/browser/parts/sessionsParts.js +17 -2
  64. package/vscode/src/vs/sessions/browser/sessionWorkspace.d.ts +6 -3
  65. package/vscode/src/vs/sessions/browser/sessionWorkspace.js +2 -2
  66. package/vscode/src/vs/sessions/browser/sessionsSetUpService.js +66 -20
  67. package/vscode/src/vs/sessions/browser/sessionsSignInDialog.d.ts +1 -0
  68. package/vscode/src/vs/sessions/browser/sessionsSignInDialog.js +5 -4
  69. package/vscode/src/vs/sessions/browser/workbenchFactory.d.ts +12 -0
  70. package/vscode/src/vs/sessions/browser/workbenchFactory.js +17 -0
  71. package/vscode/src/vs/sessions/contrib/accountMenu/browser/account.contribution.d.ts +85 -1
  72. package/vscode/src/vs/sessions/contrib/accountMenu/browser/account.contribution.js +118 -100
  73. package/vscode/src/vs/sessions/contrib/accountMenu/browser/chatPetAchievementBadges.d.ts +3 -2
  74. package/vscode/src/vs/sessions/contrib/accountMenu/browser/chatPetAchievementBadges.js +39 -34
  75. package/vscode/src/vs/sessions/contrib/accountMenu/browser/media/accountTitleBarWidget.css +6 -0
  76. package/vscode/src/vs/sessions/contrib/agentFeedback/browser/nullAgentFeedbackService.contribution.d.ts +3 -0
  77. package/vscode/src/vs/sessions/contrib/agentFeedback/browser/nullAgentFeedbackService.contribution.js +6 -0
  78. package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeView.contribution.js +18 -18
  79. package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeViewViews.js +12 -12
  80. package/vscode/src/vs/sessions/contrib/applyCommitsToParentRepo/browser/applyChangesToParentRepo.js +7 -7
  81. package/vscode/src/vs/sessions/contrib/aquarium/browser/aquarium.contribution.js +12 -12
  82. package/vscode/src/vs/sessions/contrib/aquarium/browser/aquariumOverlay.js +10 -10
  83. package/vscode/src/vs/sessions/contrib/automations/browser/automationDialog.d.ts +78 -8
  84. package/vscode/src/vs/sessions/contrib/automations/browser/automationDialog.js +1166 -202
  85. package/vscode/src/vs/sessions/contrib/automations/browser/automationDialogService.d.ts +11 -1
  86. package/vscode/src/vs/sessions/contrib/automations/browser/automationDialogService.js +190 -69
  87. package/vscode/src/vs/sessions/contrib/automations/browser/automationRunner.d.ts +11 -9
  88. package/vscode/src/vs/sessions/contrib/automations/browser/automationRunner.js +122 -233
  89. package/vscode/src/vs/sessions/contrib/automations/browser/automationTelemetry.d.ts +22 -0
  90. package/vscode/src/vs/sessions/contrib/automations/browser/automationTelemetry.js +62 -0
  91. package/vscode/src/vs/sessions/contrib/automations/browser/automationTools.d.ts +7 -2
  92. package/vscode/src/vs/sessions/contrib/automations/browser/automationTools.js +172 -84
  93. package/vscode/src/vs/sessions/contrib/automations/browser/automations.contribution.js +17 -7
  94. package/vscode/src/vs/sessions/contrib/automations/browser/media/automationDialog.css +242 -60
  95. package/vscode/src/vs/sessions/contrib/automations/browser/providerAutomationService.d.ts +24 -36
  96. package/vscode/src/vs/sessions/contrib/automations/browser/providerAutomationService.js +104 -420
  97. package/vscode/src/vs/sessions/contrib/changes/browser/changes.contribution.js +15 -14
  98. package/vscode/src/vs/sessions/contrib/changes/browser/changesActions.d.ts +13 -3
  99. package/vscode/src/vs/sessions/contrib/changes/browser/changesActions.js +66 -43
  100. package/vscode/src/vs/sessions/contrib/changes/browser/changesMultiDiffSourceResolver.js +2 -7
  101. package/vscode/src/vs/sessions/contrib/changes/browser/changesViewActions.js +54 -59
  102. package/vscode/src/vs/sessions/contrib/changes/browser/changesetReviewActions.js +7 -7
  103. package/vscode/src/vs/sessions/contrib/changes/browser/media/changesActions.css +6 -0
  104. package/vscode/src/vs/sessions/contrib/changes/browser/sessionSyncChanges.js +25 -21
  105. package/vscode/src/vs/sessions/contrib/changes/browser/sessionsChangesAccessibilityHelp.js +21 -27
  106. package/vscode/src/vs/sessions/contrib/chat/browser/sessionChatInputToolbarDebug.js +17 -17
  107. package/vscode/src/vs/sessions/contrib/chat/browser/sessionTaskRunner.d.ts +5 -5
  108. package/vscode/src/vs/sessions/contrib/chat/browser/sessionTaskRunner.js +2 -2
  109. package/vscode/src/vs/sessions/contrib/chatDebug/browser/chatDebug.contribution.js +2 -2
  110. package/vscode/src/vs/sessions/contrib/codeReview/browser/codeReview.contributions.js +9 -16
  111. package/vscode/src/vs/sessions/contrib/customViewTest/browser/customViewTest.contribution.js +7 -7
  112. package/vscode/src/vs/sessions/contrib/editor/browser/addTabActions.js +10 -10
  113. package/vscode/src/vs/sessions/contrib/editor/browser/editor.contribution.d.ts +13 -1
  114. package/vscode/src/vs/sessions/contrib/editor/browser/editor.contribution.js +104 -117
  115. package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditor.contribution.js +8 -7
  116. package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditor.js +5 -5
  117. package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditorInput.js +1 -1
  118. package/vscode/src/vs/sessions/contrib/editor/browser/media/editorBreadcrumbs.css +0 -1
  119. package/vscode/src/vs/sessions/contrib/editor/browser/media/editorHeader.css +1 -1
  120. package/vscode/src/vs/sessions/contrib/files/browser/files.contribution.d.ts +7 -0
  121. package/vscode/src/vs/sessions/contrib/files/browser/files.contribution.js +77 -13
  122. package/vscode/src/vs/sessions/contrib/files/browser/filesView.d.ts +2 -1
  123. package/vscode/src/vs/sessions/contrib/files/browser/filesView.js +14 -4
  124. package/vscode/src/vs/sessions/contrib/layout/browser/baseSessionLayoutController.d.ts +45 -10
  125. package/vscode/src/vs/sessions/contrib/layout/browser/baseSessionLayoutController.js +527 -77
  126. package/vscode/src/vs/sessions/contrib/layout/browser/chatLayoutOwnerKeys.d.ts +18 -0
  127. package/vscode/src/vs/sessions/contrib/layout/browser/chatLayoutOwnerKeys.js +95 -0
  128. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDetailPanelCoordinator.d.ts → desktop/desktopDetailPanelCoordinator.d.ts} +5 -4
  129. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDetailPanelCoordinator.js → desktop/desktopDetailPanelCoordinator.js} +10 -7
  130. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDockedTabsCoordinator.d.ts → desktop/desktopDockedTabsCoordinator.d.ts} +15 -12
  131. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDockedTabsCoordinator.js → desktop/desktopDockedTabsCoordinator.js} +91 -44
  132. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDraftSessionStrategy.d.ts → desktop/desktopDraftSessionStrategy.d.ts} +10 -5
  133. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDraftSessionStrategy.js → desktop/desktopDraftSessionStrategy.js} +95 -22
  134. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneExistingSessionStrategy.d.ts → desktop/desktopExistingSessionStrategy.d.ts} +13 -11
  135. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneExistingSessionStrategy.js → desktop/desktopExistingSessionStrategy.js} +137 -57
  136. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneLayoutStrategy.d.ts → desktop/desktopLayoutStrategy.d.ts} +22 -13
  137. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneLayoutStrategy.js → desktop/desktopLayoutStrategy.js} +2 -2
  138. package/vscode/src/vs/sessions/contrib/layout/browser/desktop/desktopOwnerCompositionStore.d.ts +22 -0
  139. package/vscode/src/vs/sessions/contrib/layout/browser/desktop/desktopOwnerCompositionStore.js +136 -0
  140. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneSharedHelpers.d.ts → desktop/desktopSharedHelpers.d.ts} +9 -2
  141. package/vscode/src/vs/sessions/contrib/layout/browser/desktop/desktopSharedHelpers.js +56 -0
  142. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneVisibilityProfileStore.d.ts → desktop/desktopVisibilityProfileStore.d.ts} +3 -2
  143. package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneVisibilityProfileStore.js → desktop/desktopVisibilityProfileStore.js} +10 -9
  144. package/vscode/src/vs/sessions/contrib/layout/browser/desktopLayoutController.d.ts +71 -0
  145. package/vscode/src/vs/sessions/contrib/layout/browser/desktopLayoutController.js +201 -0
  146. package/vscode/src/vs/sessions/contrib/layout/browser/sessions.layout.contribution.d.ts +8 -1
  147. package/vscode/src/vs/sessions/contrib/layout/browser/sessions.layout.contribution.js +35 -35
  148. package/vscode/src/vs/sessions/contrib/layout/common/sessionEditorWorkingSet.d.ts +39 -0
  149. package/vscode/src/vs/sessions/contrib/layout/common/sessionEditorWorkingSet.js +73 -0
  150. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionTourContribution.d.ts +42 -1
  151. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionTourContribution.js +14 -10
  152. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewTourContribution.js +3 -4
  153. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewTourTrigger.d.ts +2 -2
  154. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewTourTrigger.js +13 -9
  155. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV2TourContribution.js +20 -5
  156. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV2TourVariation.d.ts +8 -0
  157. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV2TourVariation.js +19 -0
  158. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV3Prompt.js +21 -20
  159. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionTour.js +10 -5
  160. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTour.js +12 -8
  161. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTourShared.d.ts +3 -1
  162. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTourShared.js +12 -7
  163. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV2Tour.d.ts +9 -1
  164. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV2Tour.js +46 -19
  165. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV3Tour.js +2 -0
  166. package/vscode/src/vs/sessions/contrib/policyBlocked/browser/media/sessionsPolicyBlocked.css +33 -0
  167. package/vscode/src/vs/sessions/contrib/policyBlocked/browser/policyBlocked.contribution.d.ts +4 -2
  168. package/vscode/src/vs/sessions/contrib/policyBlocked/browser/policyBlocked.contribution.js +29 -8
  169. package/vscode/src/vs/sessions/contrib/policyBlocked/browser/sessionsPolicyBlocked.d.ts +15 -2
  170. package/vscode/src/vs/sessions/contrib/policyBlocked/browser/sessionsPolicyBlocked.js +169 -32
  171. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostForkActions.js +30 -8
  172. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionBranchActions.js +8 -34
  173. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentMergeActions.js +63 -49
  174. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/exportDebugLogsAction.js +1 -1
  175. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatInputConfigPicker.js +31 -17
  176. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnostics.contribution.d.ts +32 -0
  177. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnostics.contribution.js +250 -0
  178. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsLogs.d.ts +6 -0
  179. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsLogs.js +52 -0
  180. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsReport.d.ts +51 -0
  181. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsReport.js +439 -0
  182. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsService.d.ts +45 -0
  183. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsService.js +595 -0
  184. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerAgentHostService.d.ts +20 -3
  185. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerAgentHostService.js +360 -46
  186. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerSource.d.ts +9 -0
  187. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerSource.js +59 -0
  188. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/media/connectionDiagnostics.css +201 -0
  189. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/getRemoteSessionTool.d.ts +10 -0
  190. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/getRemoteSessionTool.js +70 -0
  191. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionChatService.d.ts +20 -0
  192. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionChatService.js +104 -0
  193. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionInspector.d.ts +15 -0
  194. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionInspector.js +152 -0
  195. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionMessageRouter.d.ts +49 -0
  196. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionMessageRouter.js +340 -0
  197. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionService.d.ts +41 -0
  198. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionService.js +400 -0
  199. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionSource.d.ts +28 -0
  200. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionSource.js +178 -0
  201. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionTools.d.ts +17 -0
  202. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionTools.js +206 -0
  203. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessions.contribution.d.ts +1 -0
  204. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessions.contribution.js +58 -0
  205. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/sendRemoteMessageTool.d.ts +10 -0
  206. package/vscode/src/vs/sessions/contrib/remoteSessions/browser/sendRemoteMessageTool.js +90 -0
  207. package/vscode/src/vs/sessions/contrib/remoteSessions/common/remoteSessionInspection.d.ts +38 -0
  208. package/vscode/src/vs/sessions/contrib/remoteSessions/common/remoteSessionInspection.js +58 -0
  209. package/vscode/src/vs/sessions/contrib/search/browser/search.contribution.js +4 -5
  210. package/vscode/src/vs/sessions/contrib/search/browser/searchEditorEmptyState.contribution.js +1 -1
  211. package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparison.contribution.d.ts +1 -0
  212. package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparison.contribution.js +33 -0
  213. package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonGridController.d.ts +30 -0
  214. package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonGridController.js +190 -0
  215. package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonTool.d.ts +31 -0
  216. package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonTool.js +559 -0
  217. package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonViewService.d.ts +12 -0
  218. package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonViewService.js +38 -0
  219. package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsIndicatorModel.d.ts +13 -4
  220. package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsIndicatorModel.js +155 -22
  221. package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsList.js +9 -5
  222. package/vscode/src/vs/sessions/contrib/sessions/browser/media/automationsCards.css +90 -25
  223. package/vscode/src/vs/sessions/contrib/sessions/browser/media/sessionsTitleBarWidget.css +21 -4
  224. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionDetailsAction.d.ts +2 -1
  225. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionDetailsAction.js +11 -7
  226. package/vscode/src/vs/sessions/contrib/sessions/browser/sessions.contribution.d.ts +116 -1
  227. package/vscode/src/vs/sessions/contrib/sessions/browser/sessions.contribution.js +126 -30
  228. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsAccountTelemetry.d.ts +26 -0
  229. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsAccountTelemetry.js +160 -0
  230. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsActions.d.ts +14 -6
  231. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsActions.js +555 -151
  232. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsLifecycleTracker.d.ts +192 -0
  233. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsLifecycleTracker.js +510 -0
  234. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTelemetry.contribution.d.ts +6 -7
  235. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTelemetry.contribution.js +64 -57
  236. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTitleBarWidget.d.ts +5 -3
  237. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTitleBarWidget.js +83 -51
  238. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsWindowNotifier.d.ts +5 -1
  239. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsWindowNotifier.js +33 -12
  240. package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationCataloguePresentation.d.ts +3 -0
  241. package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationCataloguePresentation.js +53 -0
  242. package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationTemplates.js +10 -10
  243. package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsAccessibility.d.ts +2 -2
  244. package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsAccessibility.js +103 -55
  245. package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsView.d.ts +7 -1
  246. package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsView.js +679 -325
  247. package/vscode/src/vs/sessions/contrib/sessions/browser/views/sessionsViewActions.d.ts +27 -1
  248. package/vscode/src/vs/sessions/contrib/sessions/browser/views/sessionsViewActions.js +508 -163
  249. package/vscode/src/vs/sessions/contrib/terminal/browser/agentHostSessionTaskRunner.d.ts +20 -2
  250. package/vscode/src/vs/sessions/contrib/terminal/browser/agentHostSessionTaskRunner.js +100 -17
  251. package/vscode/src/vs/sessions/contrib/terminal/browser/sessionsTerminalContribution.d.ts +5 -1
  252. package/vscode/src/vs/sessions/contrib/terminal/browser/sessionsTerminalContribution.js +108 -30
  253. package/vscode/src/vs/sessions/contrib/workspace/browser/workspaceFolderManagement.d.ts +5 -3
  254. package/vscode/src/vs/sessions/contrib/workspace/browser/workspaceFolderManagement.js +47 -35
  255. package/vscode/src/vs/sessions/services/agentHostFilter/browser/agentHostFilterService.d.ts +9 -4
  256. package/vscode/src/vs/sessions/services/agentHostFilter/browser/agentHostFilterService.js +75 -25
  257. package/vscode/src/vs/sessions/services/customView/browser/customViewService.d.ts +11 -4
  258. package/vscode/src/vs/sessions/services/customView/browser/customViewService.js +17 -9
  259. package/vscode/src/vs/sessions/services/sessions/browser/closedItemHistory.d.ts +5 -0
  260. package/vscode/src/vs/sessions/services/sessions/browser/closedItemHistory.js +20 -2
  261. package/vscode/src/vs/sessions/services/sessions/browser/sessionComparisonService.d.ts +75 -0
  262. package/vscode/src/vs/sessions/services/sessions/browser/sessionComparisonService.js +1135 -0
  263. package/vscode/src/vs/sessions/services/sessions/browser/sessionGridState.d.ts +17 -0
  264. package/vscode/src/vs/sessions/services/sessions/browser/sessionGridState.js +99 -0
  265. package/vscode/src/vs/sessions/services/sessions/browser/sessionGroupsService.d.ts +4 -0
  266. package/vscode/src/vs/sessions/services/sessions/browser/sessionGroupsService.js +88 -23
  267. package/vscode/src/vs/sessions/services/sessions/browser/sessionNavigation.d.ts +19 -26
  268. package/vscode/src/vs/sessions/services/sessions/browser/sessionNavigation.js +115 -74
  269. package/vscode/src/vs/sessions/services/sessions/browser/sessionsListModelService.js +1 -1
  270. package/vscode/src/vs/sessions/services/sessions/browser/sessionsManagementService.d.ts +22 -7
  271. package/vscode/src/vs/sessions/services/sessions/browser/sessionsManagementService.js +278 -60
  272. package/vscode/src/vs/sessions/services/sessions/browser/sessionsRecencyHistory.d.ts +17 -20
  273. package/vscode/src/vs/sessions/services/sessions/browser/sessionsRecencyHistory.js +33 -22
  274. package/vscode/src/vs/sessions/services/sessions/browser/sessionsService.d.ts +28 -8
  275. package/vscode/src/vs/sessions/services/sessions/browser/sessionsService.js +673 -160
  276. package/vscode/src/vs/sessions/services/sessions/browser/visibleSessions.d.ts +13 -4
  277. package/vscode/src/vs/sessions/services/sessions/browser/visibleSessions.js +105 -15
  278. package/vscode/src/vs/sessions/services/sessions/common/sessionContextKeys.js +53 -34
  279. package/vscode/src/vs/sessions/services/workspaceFolderLabel/browser/workspaceFolderLabelService.js +1 -1
  280. package/vscode/src/vs/workbench/browser/layout.js +1 -1
  281. package/vscode/src/vs/workbench/browser/workbench.d.ts +0 -2
  282. package/vscode/src/vs/workbench/browser/workbench.js +23 -20
  283. package/vscode/src/vs/workbench/contrib/chat/common/automations/schedule.d.ts +6 -0
  284. package/vscode/src/vs/workbench/contrib/chat/common/automations/schedule.js +41 -0
  285. package/vscode/src/vs/workbench/contrib/chat/common/chatUsage.d.ts +15 -0
  286. package/vscode/src/vs/workbench/contrib/chat/common/chatUsage.js +56 -0
  287. package/vscode/src/vs/platform/agentHost/common/meta/agentCheckoutOperationMeta.d.ts +0 -18
  288. package/vscode/src/vs/platform/agentHost/common/meta/agentCheckoutOperationMeta.js +0 -27
  289. package/vscode/src/vs/sessions/browser/parts/singlePaneAuxiliaryBarPart.js +0 -36
  290. package/vscode/src/vs/sessions/contrib/automations/browser/automationLeaderElection.d.ts +0 -37
  291. package/vscode/src/vs/sessions/contrib/automations/browser/automationLeaderElection.js +0 -126
  292. package/vscode/src/vs/sessions/contrib/automations/browser/automationScheduler.d.ts +0 -59
  293. package/vscode/src/vs/sessions/contrib/automations/browser/automationScheduler.js +0 -232
  294. package/vscode/src/vs/sessions/contrib/automations/browser/automationStorageService.d.ts +0 -13
  295. package/vscode/src/vs/sessions/contrib/automations/browser/automationStorageService.js +0 -22
  296. package/vscode/src/vs/sessions/contrib/blockedSessions/browser/blockedSessions.d.ts +0 -45
  297. package/vscode/src/vs/sessions/contrib/blockedSessions/browser/blockedSessions.js +0 -110
  298. package/vscode/src/vs/sessions/contrib/layout/browser/desktopSessionLayoutController.d.ts +0 -112
  299. package/vscode/src/vs/sessions/contrib/layout/browser/desktopSessionLayoutController.js +0 -444
  300. package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneSharedHelpers.js +0 -43
  301. package/vscode/src/vs/sessions/contrib/layout/browser/singlePaneLayoutController.d.ts +0 -55
  302. package/vscode/src/vs/sessions/contrib/layout/browser/singlePaneLayoutController.js +0 -91
  303. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostClaudePermissionModePicker.d.ts +0 -26
  304. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostClaudePermissionModePicker.js +0 -98
  305. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostCodexApprovalsPicker.d.ts +0 -33
  306. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostCodexApprovalsPicker.js +0 -98
  307. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModeIcon.d.ts +0 -2
  308. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModeIcon.js +0 -13
  309. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModePicker.d.ts +0 -122
  310. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModePicker.js +0 -464
  311. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerActionItem.d.ts +0 -35
  312. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerActionItem.js +0 -90
  313. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerDelegate.d.ts +0 -84
  314. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerDelegate.js +0 -328
  315. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionConfigPicker.d.ts +0 -174
  316. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionConfigPicker.js +0 -1390
  317. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/media/agentHostSessionConfigPicker.css +0 -44
  318. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileAgentHostModePicker.d.ts +0 -30
  319. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileAgentHostModePicker.js +0 -78
  320. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatPhoneInputTarget.d.ts +0 -11
  321. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatPhoneInputTarget.js +0 -26
  322. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/remoteAgentHostConnectionCustomization.d.ts +0 -27
  323. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/remoteAgentHostConnectionCustomization.js +0 -26
@@ -0,0 +1,1135 @@
1
+
2
+ import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
+ import { CancellationToken } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
4
+ import { isCancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
5
+ import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
6
+ import { parse, stringify } from '@codingame/monaco-vscode-api/vscode/vs/base/common/marshalling';
7
+ import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
8
+ import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri';
9
+ import { generateUuid } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uuid';
10
+ import '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/extensions';
11
+ import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
12
+ import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
13
+ import { IStorageService } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service';
14
+ import { ITelemetryService } from '@codingame/monaco-vscode-api/vscode/vs/platform/telemetry/common/telemetry.service';
15
+ import { withSessionComparisonMetadata } from '@codingame/monaco-vscode-api/vscode/vs/platform/agentHost/common/state/sessionState';
16
+ import { createSessionComparisonJudgePrompt } from '../../../../platform/agentHost/common/sessionComparisonPrompts.js';
17
+ import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
18
+ import { IChatRequestVariableEntry } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/attachments/chatVariableEntries';
19
+ import { IChatService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/chatService/chatService.service';
20
+ import { aggregateChatUsage } from '../../../../workbench/contrib/chat/common/chatUsage.js';
21
+ import { SessionStatus, isActiveSessionStatus } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/common/session';
22
+ import { ISessionGroupsService } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/browser/sessionGroupsService.service';
23
+ import { ISessionsManagementService } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/common/sessionsManagement.service';
24
+ import { SESSION_COMPARISON_MAX_ATTEMPTS, SessionComparisonParticipantRole, getSessionComparisonHarnessLabel, SESSION_COMPARISON_SYNTHESIS_INSTRUCTIONS_MAX_LENGTH, getSessionComparisonAttemptLabel, SESSION_COMPARISON_MANIFEST_LIST_MAX_ITEMS, getBoundedSessionComparisonManifestText } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/common/sessionComparison';
25
+ import '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
26
+ import { hashSessionIdForTelemetry, logSessionComparisonAttemptCompleted, logSessionComparisonModelOutcome, getSessionsTelemetryModelId, getSessionsTelemetryAgentId, getSessionsTelemetryProviderId } from '@codingame/monaco-vscode-api/vscode/vs/sessions/common/sessionsTelemetry';
27
+ import { observableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
28
+
29
+ var SessionComparisonService_1;
30
+ function getAttemptUnavailableMessage() {
31
+ return localize(6315, "The attempt session is no longer available.");
32
+ }
33
+ let SessionComparisonService = class SessionComparisonService extends Disposable {
34
+ static {
35
+ SessionComparisonService_1 = this;
36
+ }
37
+ static {
38
+ this.STORAGE_KEY = "sessions.comparisons";
39
+ }
40
+ static {
41
+ this.ATTEMPT_TELEMETRY_STORAGE_KEY = "sessions.comparisonAttemptTelemetry";
42
+ }
43
+ constructor(
44
+ sessionsManagementService,
45
+ sessionGroupsService,
46
+ storageService,
47
+ logService,
48
+ chatService,
49
+ telemetryService
50
+ ) {
51
+ super();
52
+ this.sessionsManagementService = sessionsManagementService;
53
+ this.sessionGroupsService = sessionGroupsService;
54
+ this.storageService = storageService;
55
+ this.logService = logService;
56
+ this.chatService = chatService;
57
+ this.telemetryService = telemetryService;
58
+ this._comparisons = observableValue(this, []);
59
+ this.comparisons = this._comparisons;
60
+ this._judgeStarting = ( new Set());
61
+ this._synthesisStarting = ( new Set());
62
+ this._migratingAttemptTitles = ( new Set());
63
+ this._migratedAttemptTitles = ( new Set());
64
+ this._reportedAttemptTelemetry = ( new Set());
65
+ this._comparisonIdsBySession = ( new Map());
66
+ this._loadAttemptTelemetryState();
67
+ const comparisons = this._load();
68
+ this._comparisons.set(comparisons, undefined);
69
+ for (const comparison of comparisons) {
70
+ this._indexComparisonSessions(comparison);
71
+ }
72
+ this._archiveComparisonsWithMissingGroups();
73
+ this._pruneAttemptTelemetryState(( new Set(
74
+ this._comparisons.get().filter(comparison => comparison.archivedAt === undefined).map(comparison => comparison.id)
75
+ )));
76
+ this._ensureComparisonGroupMembership(this._comparisons.get());
77
+ this._migrateLegacyAttemptTitles(this._comparisons.get());
78
+ this._register(this.sessionsManagementService.onDidChangeSessions(event => {
79
+ const comparisons = this._getComparisonsForSessionChanges(event);
80
+ const reconciled = comparisons.map(comparison => this._reconcileSessionAvailability(comparison, event));
81
+ this._archiveFullyArchivedComparisons(reconciled);
82
+ const activeComparisons = reconciled.filter(comparison => this.getComparison(comparison.id)?.archivedAt === undefined);
83
+ this._ensureComparisonGroupMembership(activeComparisons);
84
+ this._migrateLegacyAttemptTitles(activeComparisons);
85
+ this._checkComparisons(activeComparisons);
86
+ }));
87
+ this._register(
88
+ this.sessionsManagementService.onDidDeleteSession(session => this._markParticipantDeleted(session))
89
+ );
90
+ this._register(this.sessionGroupsService.onDidChange(event => {
91
+ if (event.groupsChanged) {
92
+ this._archiveComparisonsWithMissingGroups();
93
+ }
94
+ }));
95
+ this._checkComparisons(this._comparisons.get());
96
+ }
97
+ async startComparison(options, token = CancellationToken.None) {
98
+ if (options.attempts.length < 2 || options.attempts.length > SESSION_COMPARISON_MAX_ATTEMPTS) {
99
+ throw ( new Error("A session comparison requires between two and ten attempts."));
100
+ }
101
+ if (options.synthesisHarness && !options.judgeHarness) {
102
+ throw ( new Error("A synthesis model requires a Judge model."));
103
+ }
104
+ if (( new Set(options.attempts.map(attempt => attempt.id))).size !== options.attempts.length) {
105
+ throw ( new Error("Session comparison attempt identifiers must be unique."));
106
+ }
107
+ const id = generateUuid();
108
+ const attachedContext = options.attachedContext ? snapshotAttachedContext(options.attachedContext) : undefined;
109
+ const title = comparisonTitle(options.prompt);
110
+ const group = this.sessionGroupsService.createGroup(title);
111
+ const attempts = options.attempts.map(attempt => ({
112
+ id: attempt.id,
113
+ role: SessionComparisonParticipantRole.Attempt,
114
+ harness: attempt.harness
115
+ }));
116
+ let comparison = {
117
+ id,
118
+ groupId: group.id,
119
+ title,
120
+ createdAt: Date.now(),
121
+ workspace: options.workspace,
122
+ prompt: options.prompt,
123
+ launching: true,
124
+ attachedContext,
125
+ branch: options.branch,
126
+ permissionLevel: options.permissionLevel,
127
+ judgeHarness: options.judgeHarness,
128
+ synthesisHarness: options.synthesisHarness,
129
+ participants: attempts
130
+ };
131
+ this._addComparison(comparison);
132
+ const attemptPromises = attempts.map(async (participant, index) => {
133
+ const harness = participant.harness;
134
+ try {
135
+ const session = await this.sessionsManagementService.createAndSendNewChatRequest(options.workspace, {
136
+ query: options.prompt,
137
+ attachedContext: comparison.attachedContext ? [...comparison.attachedContext] : undefined,
138
+ title: getSessionComparisonHarnessLabel(participant),
139
+ background: true
140
+ }, {
141
+ ...this._createOptions(harness, options, id, index),
142
+ onSessionCreated: createdSession => {
143
+ this._updateComparisonParticipant(id, participant.id, currentParticipant => ({
144
+ ...currentParticipant,
145
+ sessionResource: createdSession.resource,
146
+ launchError: undefined
147
+ }));
148
+ }
149
+ }, token);
150
+ return {
151
+ ...participant,
152
+ sessionResource: session?.resource,
153
+ ...(!session ? {
154
+ launchError: ( localize(6316, "The session did not start."))
155
+ } : {})
156
+ };
157
+ } catch (error) {
158
+ return {
159
+ ...participant,
160
+ launchError: isCancellationError(error) ? ( localize(6317, "The attempt was cancelled before it started.")) : error instanceof Error ? error.message : String(error)
161
+ };
162
+ }
163
+ });
164
+ const launchedAttempts = await Promise.all(attemptPromises);
165
+ const current = this.getComparison(comparison.id);
166
+ if (!current) {
167
+ throw ( new Error("Session comparison was removed while attempts were launching."));
168
+ }
169
+ const launchedById = ( new Map(launchedAttempts.map(participant => [participant.id, participant])));
170
+ comparison = {
171
+ ...current,
172
+ launching: undefined,
173
+ participants: current.participants.map(participant => launchedById.get(participant.id) ?? participant)
174
+ };
175
+ this._ensureComparisonGroupMembership([comparison]);
176
+ this._replaceComparison(comparison);
177
+ this._checkComparison(comparison);
178
+ const successfulAttemptCount = launchedAttempts.filter(participant => participant.sessionResource).length;
179
+ if (successfulAttemptCount < 2) {
180
+ this._removeComparison(comparison.id);
181
+ this.sessionGroupsService.deleteGroup(comparison.groupId);
182
+ const launchFailures = launchedAttempts.filter(participant => participant.launchError).map(
183
+ participant => `${getSessionComparisonHarnessLabel(participant)}: ${participant.launchError}`
184
+ ).join("; ");
185
+ throw ( new Error(( localize(
186
+ 6318,
187
+ "Only {0} of {1} comparison attempts started. At least two must start successfully. Failed attempts: {2}",
188
+ successfulAttemptCount,
189
+ attempts.length,
190
+ launchFailures
191
+ ))));
192
+ }
193
+ return comparison;
194
+ }
195
+ getComparison(comparisonId) {
196
+ return this._comparisons.get().find(comparison => comparison.id === comparisonId);
197
+ }
198
+ getComparisonForSession(resource) {
199
+ const comparisonId = this._comparisonIdsBySession.get(( resource.toString()));
200
+ return comparisonId ? this.getComparison(comparisonId) : undefined;
201
+ }
202
+ cancelComparison(comparisonId) {
203
+ const comparison = this._requireComparison(comparisonId);
204
+ if (comparison.cancelledAt !== undefined) {
205
+ return;
206
+ }
207
+ this._replaceComparison({
208
+ ...comparison,
209
+ cancelledAt: Date.now(),
210
+ synthesisPlan: undefined
211
+ });
212
+ }
213
+ archiveComparison(comparisonId) {
214
+ const comparison = this._requireComparison(comparisonId);
215
+ if (comparison.archivedAt !== undefined) {
216
+ return;
217
+ }
218
+ this._replaceComparison({
219
+ ...comparison,
220
+ archivedAt: Date.now()
221
+ });
222
+ this._pruneAttemptTelemetryState(( new Set(
223
+ this._comparisons.get().filter(candidate => candidate.archivedAt === undefined).map(candidate => candidate.id)
224
+ )));
225
+ }
226
+ selectAttempt(comparisonId, participantId) {
227
+ const comparison = this._requireComparison(comparisonId);
228
+ const participant = comparison.participants.find(
229
+ candidate => candidate.id === participantId && candidate.role === SessionComparisonParticipantRole.Attempt && candidate.sessionResource
230
+ );
231
+ if (!participant) {
232
+ throw ( new Error(`Comparison attempt '${participantId}' was not found.`));
233
+ }
234
+ this._replaceComparison({
235
+ ...comparison,
236
+ selectedParticipantId: participantId
237
+ });
238
+ }
239
+ submitVerdict(comparisonId, verdict) {
240
+ const comparison = this._requireComparison(comparisonId);
241
+ if (comparison.cancelledAt !== undefined) {
242
+ throw ( new Error(`Comparison '${comparisonId}' was cancelled.`));
243
+ }
244
+ if (comparison.verdict) {
245
+ throw ( new Error(`A verdict has already been submitted for comparison '${comparisonId}'.`));
246
+ }
247
+ const attemptIds = ( new Set(comparison.participants.filter(
248
+ participant => participant.role === SessionComparisonParticipantRole.Attempt && participant.sessionResource
249
+ ).map(participant => participant.id)));
250
+ if (!( attemptIds.has(verdict.recommendedParticipantId))) {
251
+ throw ( new Error(
252
+ `Recommended comparison attempt '${verdict.recommendedParticipantId}' was not found.`
253
+ ));
254
+ }
255
+ if (( verdict.attempts.some(attempt => !( attemptIds.has(attempt.participantId))))) {
256
+ throw ( new Error("The comparison verdict contains an unknown attempt."));
257
+ }
258
+ const updated = {
259
+ ...comparison,
260
+ verdict,
261
+ synthesisPlan: undefined
262
+ };
263
+ this._replaceComparison(updated);
264
+ this._reportOutcomeTelemetry(comparison, verdict);
265
+ this._checkComparison(updated);
266
+ }
267
+ canRetryJudge(comparisonId) {
268
+ const comparison = this.getComparison(comparisonId);
269
+ return !!comparison && !!comparison.judgeHarness && comparison.cancelledAt === undefined && comparison.archivedAt === undefined && !( this._judgeStarting.has(comparisonId)) && ( comparison.participants.some(
270
+ participant => participant.role === SessionComparisonParticipantRole.Judge && !participant.sessionResource
271
+ ));
272
+ }
273
+ retryJudge(comparisonId) {
274
+ if (!this.canRetryJudge(comparisonId)) {
275
+ return;
276
+ }
277
+ const comparison = this._requireComparison(comparisonId);
278
+ const failedJudgeIds = comparison.participants.filter(
279
+ participant => participant.role === SessionComparisonParticipantRole.Judge && !participant.sessionResource
280
+ ).map(participant => participant.id);
281
+ const updated = {
282
+ ...comparison,
283
+ participants: comparison.participants.filter(participant => !failedJudgeIds.includes(participant.id))
284
+ };
285
+ this._replaceComparison(updated);
286
+ this._checkComparison(updated);
287
+ }
288
+ setSynthesisPlan(comparisonId, plan) {
289
+ const comparison = this._requireComparison(comparisonId);
290
+ if (comparison.cancelledAt !== undefined) {
291
+ throw ( new Error(`Comparison '${comparisonId}' was cancelled.`));
292
+ }
293
+ if (!plan) {
294
+ this._replaceComparison({
295
+ ...comparison,
296
+ synthesisPlan: undefined
297
+ });
298
+ return;
299
+ }
300
+ if (plan.instructions !== undefined && (plan.instructions.trim().length === 0 || plan.instructions.length > SESSION_COMPARISON_SYNTHESIS_INSTRUCTIONS_MAX_LENGTH)) {
301
+ throw ( new Error("The synthesis plan contains invalid additional instructions."));
302
+ }
303
+ this._replaceComparison({
304
+ ...comparison,
305
+ synthesisPlan: {
306
+ instructions: plan.instructions
307
+ }
308
+ });
309
+ }
310
+ async synthesize(comparisonId) {
311
+ if (( this._synthesisStarting.has(comparisonId))) {
312
+ return;
313
+ }
314
+ const comparison = this._requireComparison(comparisonId);
315
+ if (comparison.cancelledAt !== undefined) {
316
+ throw ( new Error(`Comparison '${comparisonId}' was cancelled.`));
317
+ }
318
+ if (comparison.archivedAt !== undefined) {
319
+ throw ( new Error(`Comparison '${comparisonId}' was archived.`));
320
+ }
321
+ if (( comparison.participants.some(
322
+ participant => participant.role === SessionComparisonParticipantRole.Synthesis
323
+ ))) {
324
+ return;
325
+ }
326
+ const recommendedId = comparison.selectedParticipantId ?? comparison.verdict?.recommendedParticipantId;
327
+ const recommended = comparison.participants.find(
328
+ participant => participant.id === recommendedId && participant.role === SessionComparisonParticipantRole.Attempt && participant.sessionResource
329
+ );
330
+ if (!recommended) {
331
+ throw ( new Error("A selected or recommended attempt is required before synthesis."));
332
+ }
333
+ const harness = comparison.synthesisHarness;
334
+ if (!harness || !comparison.verdict) {
335
+ throw ( new Error(
336
+ "A configured synthesis model and a Judge verdict are required before synthesis."
337
+ ));
338
+ }
339
+ const synthesisParticipantId = generateUuid();
340
+ this._synthesisStarting.add(comparisonId);
341
+ try {
342
+ const otherAttemptStrengthsPrompt = this._getOtherAttemptStrengthsPrompt(comparison);
343
+ const synthesisPlanPrompt = this._getSynthesisPlanPrompt(comparison);
344
+ const session = await this.sessionsManagementService.createAndSendNewChatRequest(comparison.workspace, {
345
+ query: ( localize(
346
+ 6319,
347
+ "Synthesize the strongest parts of comparison `{0}` into a new implementation.\n\n## Process\n1. Call `#readAttemptComparison` exactly once with this comparison ID.\n2. Read implementation code only from the authoritative worktrees in the manifest. If `changedFilesStatus` is unavailable, read the Git diff from that worktree.\n3. Treat additional instructions below and in the manifest as explicit user requirements. Reconcile the strongest approaches coherently instead of copying hunks mechanically.\n4. When provided, consider the strong points from other attempts below and incorporate them when they improve the solution without conflicting with user requirements.\n5. Call `get_session_context` only with an exact `sessionContextTarget` returned by the manifest and only for rationale or validation evidence. Never recover implementation code or paths from a transcript.\n6. Do not inspect another checkout, discover sessions, or guess references. Preserve correct behavior and resolve the Judge's reported conflicts.\n\n## Judge recommendation\n{1}{2}{3}\n\n## Completion\n- Run the relevant validation.\n- Respond concisely with **Changes**, **Validation**, and **Remaining issues** sections using bullet points.",
348
+ comparison.id,
349
+ this._getVerdictRecommendation(comparison),
350
+ otherAttemptStrengthsPrompt,
351
+ synthesisPlanPrompt
352
+ )),
353
+ attachedContext: comparison.attachedContext?.slice(),
354
+ title: ( localize(6320, "Synthesis: {0}", comparison.title)),
355
+ background: true
356
+ }, {
357
+ providerId: harness.providerId,
358
+ sessionTypeId: harness.sessionTypeId,
359
+ modelId: harness.modelId,
360
+ modelConfiguration: harness.modelConfiguration,
361
+ ...this._permissionOptions(harness, comparison.permissionLevel),
362
+ isolationMode: "worktree",
363
+ branch: comparison.branch,
364
+ metadata: withSessionComparisonMetadata(undefined, {
365
+ id: hashSessionIdForTelemetry(comparison.id),
366
+ role: "synthesis",
367
+ attemptCount: comparison.participants.filter(
368
+ participant => participant.role === SessionComparisonParticipantRole.Attempt
369
+ ).length
370
+ }),
371
+ onSessionCreated: createdSession => {
372
+ const current = this.getComparison(comparisonId);
373
+ if (!current || current.archivedAt !== undefined) {
374
+ return;
375
+ }
376
+ const synthesis = {
377
+ id: synthesisParticipantId,
378
+ role: SessionComparisonParticipantRole.Synthesis,
379
+ harness,
380
+ sessionResource: createdSession.resource
381
+ };
382
+ this._replaceComparison({
383
+ ...current,
384
+ participants: [...current.participants, synthesis]
385
+ });
386
+ }
387
+ });
388
+ const current = this.getComparison(comparisonId);
389
+ if (!current || current.archivedAt !== undefined) {
390
+ if (current?.participants.some(participant => participant.id === synthesisParticipantId)) {
391
+ this._replaceComparison({
392
+ ...current,
393
+ participants: current.participants.filter(participant => participant.id !== synthesisParticipantId)
394
+ });
395
+ }
396
+ if (session) {
397
+ await this._cancelAndDeleteSessions([session], "orphaned synthesis cleanup");
398
+ }
399
+ return;
400
+ }
401
+ if (session) {
402
+ this.sessionGroupsService.addToGroup(session.sessionId, current.groupId);
403
+ }
404
+ const synthesis = {
405
+ id: synthesisParticipantId,
406
+ role: SessionComparisonParticipantRole.Synthesis,
407
+ harness,
408
+ sessionResource: session?.resource,
409
+ ...(!session ? {
410
+ launchError: ( localize(6321, "The synthesis session did not start."))
411
+ } : {})
412
+ };
413
+ const registered = ( current.participants.some(participant => participant.id === synthesisParticipantId));
414
+ const updated = {
415
+ ...current,
416
+ participants: registered ? current.participants.map(
417
+ participant => participant.id === synthesisParticipantId ? synthesis : participant
418
+ ) : [...current.participants, synthesis]
419
+ };
420
+ this._replaceComparison(updated);
421
+ this._checkComparison(updated);
422
+ } catch (error) {
423
+ const current = this.getComparison(comparisonId);
424
+ if (current?.participants.some(participant => participant.id === synthesisParticipantId)) {
425
+ this._replaceComparison({
426
+ ...current,
427
+ participants: current.participants.filter(participant => participant.id !== synthesisParticipantId)
428
+ });
429
+ }
430
+ throw error;
431
+ } finally {
432
+ this._synthesisStarting.delete(comparisonId);
433
+ }
434
+ }
435
+ _updateComparisonParticipant(comparisonId, participantId, update) {
436
+ const comparison = this.getComparison(comparisonId);
437
+ if (!comparison) {
438
+ return undefined;
439
+ }
440
+ let changed = false;
441
+ const participants = comparison.participants.map(participant => {
442
+ if (participant.id !== participantId) {
443
+ return participant;
444
+ }
445
+ const updatedParticipant = update(participant);
446
+ changed = true;
447
+ return updatedParticipant;
448
+ });
449
+ if (!changed) {
450
+ return comparison;
451
+ }
452
+ const updated = {
453
+ ...comparison,
454
+ participants
455
+ };
456
+ this._replaceComparison(updated);
457
+ this._ensureComparisonGroupMembership([updated]);
458
+ return updated;
459
+ }
460
+ _createOptions(harness, options, comparisonId, attemptIndex) {
461
+ return {
462
+ providerId: harness.providerId,
463
+ sessionTypeId: harness.sessionTypeId,
464
+ modelId: harness.modelId,
465
+ modelConfiguration: harness.modelConfiguration,
466
+ ...this._permissionOptions(harness, options.permissionLevel),
467
+ isolationMode: "worktree",
468
+ branch: options.branch,
469
+ metadata: withSessionComparisonMetadata(undefined, {
470
+ id: hashSessionIdForTelemetry(comparisonId),
471
+ role: "attempt",
472
+ attemptIndex,
473
+ attemptCount: options.attempts.length
474
+ })
475
+ };
476
+ }
477
+ _permissionOptions(harness, legacyPermissionLevel) {
478
+ if (harness.permissionId) {
479
+ return {
480
+ ...(harness.modeId ? {
481
+ modeId: harness.modeId
482
+ } : {}),
483
+ permissionId: harness.permissionId
484
+ };
485
+ }
486
+ if (legacyPermissionLevel) {
487
+ return {
488
+ permissionLevel: legacyPermissionLevel
489
+ };
490
+ }
491
+ return {};
492
+ }
493
+ _requireComparison(comparisonId) {
494
+ const comparison = this.getComparison(comparisonId);
495
+ if (!comparison) {
496
+ throw ( new Error(`Session comparison '${comparisonId}' was not found.`));
497
+ }
498
+ return comparison;
499
+ }
500
+ _checkComparisons(comparisons) {
501
+ for (const comparison of comparisons) {
502
+ this._checkComparison(comparison);
503
+ }
504
+ }
505
+ _checkComparison(comparison) {
506
+ if (comparison.cancelledAt !== undefined || comparison.archivedAt !== undefined) {
507
+ return;
508
+ }
509
+ comparison = this._captureTerminalAttemptMetrics(comparison);
510
+ if (( this._judgeStarting.has(comparison.id)) || ( comparison.participants.some(participant => participant.role === SessionComparisonParticipantRole.Judge))) {
511
+ return;
512
+ }
513
+ const harness = this._getJudgeHarness(comparison);
514
+ if (!harness) {
515
+ return;
516
+ }
517
+ const attempts = comparison.participants.filter(
518
+ participant => participant.role === SessionComparisonParticipantRole.Attempt
519
+ );
520
+ let terminalAttemptCount = 0;
521
+ let completedAttemptCount = 0;
522
+ for (const participant of attempts) {
523
+ if (participant.missingSession) {
524
+ return;
525
+ }
526
+ if (participant.launchError) {
527
+ continue;
528
+ }
529
+ if (!participant.sessionResource) {
530
+ return;
531
+ }
532
+ const session = this.sessionsManagementService.getSession(participant.sessionResource);
533
+ if (!session) {
534
+ return;
535
+ }
536
+ const status = session.status.get();
537
+ if (status === SessionStatus.Completed) {
538
+ terminalAttemptCount++;
539
+ completedAttemptCount++;
540
+ continue;
541
+ }
542
+ if (status === SessionStatus.Error) {
543
+ terminalAttemptCount++;
544
+ continue;
545
+ }
546
+ return;
547
+ }
548
+ if (terminalAttemptCount < 2 || completedAttemptCount === 0) {
549
+ return;
550
+ }
551
+ const judgeParticipantId = generateUuid();
552
+ const pendingJudge = {
553
+ id: judgeParticipantId,
554
+ role: SessionComparisonParticipantRole.Judge,
555
+ harness
556
+ };
557
+ const pendingComparison = {
558
+ ...comparison,
559
+ participants: [...comparison.participants, pendingJudge]
560
+ };
561
+ this._replaceComparison(pendingComparison);
562
+ this._judgeStarting.add(comparison.id);
563
+ void this._startJudge(pendingComparison, judgeParticipantId).catch(error => {
564
+ this.logService.error("[SessionComparisonService] Failed to start the comparison judge.", error);
565
+ this._updateComparisonParticipant(comparison.id, judgeParticipantId, participant => ({
566
+ ...participant,
567
+ sessionResource: participant.sessionResource && this.sessionsManagementService.getSession(participant.sessionResource) ? participant.sessionResource : undefined,
568
+ launchError: error instanceof Error ? error.message : String(error)
569
+ }));
570
+ }).finally(() => this._judgeStarting.delete(comparison.id));
571
+ }
572
+ _captureTerminalAttemptMetrics(comparison) {
573
+ const attempts = comparison.participants.filter(
574
+ participant => participant.role === SessionComparisonParticipantRole.Attempt
575
+ );
576
+ let comparisonChanged = false;
577
+ let telemetryChanged = false;
578
+ const completions = ( new Map());
579
+ for (const [attemptIndex, participant] of attempts.entries()) {
580
+ if (!participant.sessionResource) {
581
+ continue;
582
+ }
583
+ const session = this.sessionsManagementService.getSession(participant.sessionResource);
584
+ const status = session?.status.get();
585
+ if (!session || (status !== SessionStatus.Completed && status !== SessionStatus.Error)) {
586
+ continue;
587
+ }
588
+ const requests = this.chatService.getSession(session.mainChat.get().resource)?.getRequests() ?? [];
589
+ const firstTurnElapsedMs = requests[0]?.response?.elapsedMs;
590
+ const storedElapsedMs = participant.completion?.elapsedMs;
591
+ const elapsedMs = typeof firstTurnElapsedMs === "number" && Number.isFinite(firstTurnElapsedMs) && firstTurnElapsedMs >= 0 ? firstTurnElapsedMs : typeof storedElapsedMs === "number" && storedElapsedMs > 0 ? storedElapsedMs : undefined;
592
+ const usage = aggregateChatUsage(requests.map(request => request.response?.usage));
593
+ const completion = {
594
+ elapsedMs,
595
+ tokenCount: usage ? usage.inputTokens + usage.outputTokens : participant.completion?.tokenCount,
596
+ tokenCountIsComplete: usage?.isComplete ?? participant.completion?.tokenCountIsComplete
597
+ };
598
+ completions.set(participant.id, completion);
599
+ if (participant.completion?.elapsedMs !== completion.elapsedMs || participant.completion?.tokenCount !== completion.tokenCount || participant.completion?.tokenCountIsComplete !== completion.tokenCountIsComplete) {
600
+ comparisonChanged = true;
601
+ }
602
+ const key = `${comparison.id}/${participant.id}`;
603
+ if (( this._reportedAttemptTelemetry.has(key)) || completion.elapsedMs === undefined) {
604
+ continue;
605
+ }
606
+ logSessionComparisonAttemptCompleted(this.telemetryService, {
607
+ comparisonId: hashSessionIdForTelemetry(comparison.id),
608
+ attemptIndex,
609
+ elapsedMs: completion.elapsedMs
610
+ });
611
+ this._reportedAttemptTelemetry.add(key);
612
+ telemetryChanged = true;
613
+ }
614
+ if (telemetryChanged) {
615
+ this._saveAttemptTelemetryState();
616
+ }
617
+ if (!comparisonChanged) {
618
+ return comparison;
619
+ }
620
+ const updated = {
621
+ ...comparison,
622
+ participants: comparison.participants.map(participant => {
623
+ const completion = completions.get(participant.id);
624
+ return completion && (participant.completion?.elapsedMs !== completion.elapsedMs || participant.completion?.tokenCount !== completion.tokenCount || participant.completion?.tokenCountIsComplete !== completion.tokenCountIsComplete) ? {
625
+ ...participant,
626
+ completion
627
+ } : participant;
628
+ })
629
+ };
630
+ this._replaceComparison(updated);
631
+ return updated;
632
+ }
633
+ _reportOutcomeTelemetry(comparison, verdict) {
634
+ const attempts = comparison.participants.filter(
635
+ participant => participant.role === SessionComparisonParticipantRole.Attempt
636
+ );
637
+ const judge = comparison.participants.find(participant => participant.role === SessionComparisonParticipantRole.Judge);
638
+ if (!judge) {
639
+ return;
640
+ }
641
+ const judgeSession = judge.sessionResource ? this.sessionsManagementService.getSession(judge.sessionResource) : undefined;
642
+ for (const [attemptIndex, participant] of attempts.entries()) {
643
+ if (!participant.sessionResource) {
644
+ continue;
645
+ }
646
+ const session = participant.sessionResource ? this.sessionsManagementService.getSession(participant.sessionResource) : undefined;
647
+ logSessionComparisonModelOutcome(this.telemetryService, {
648
+ comparisonId: hashSessionIdForTelemetry(comparison.id),
649
+ attemptIndex,
650
+ attemptCount: attempts.length,
651
+ providerId: getSessionsTelemetryProviderId(participant.harness.providerId),
652
+ agentId: getSessionsTelemetryAgentId(participant.harness.sessionTypeId),
653
+ modelId: getSessionsTelemetryModelId(
654
+ participant.harness.sessionTypeId,
655
+ session?.modelId.get() ?? participant.harness.modelId
656
+ ),
657
+ recommended: verdict.recommendedParticipantId === participant.id,
658
+ judgeProviderId: getSessionsTelemetryProviderId(judge.harness.providerId),
659
+ judgeAgentId: getSessionsTelemetryAgentId(judge.harness.sessionTypeId),
660
+ judgeModelId: getSessionsTelemetryModelId(
661
+ judge.harness.sessionTypeId,
662
+ judgeSession?.modelId.get() ?? judge.harness.modelId
663
+ )
664
+ });
665
+ }
666
+ }
667
+ restoreComparison(comparisonId) {
668
+ const comparison = this._requireComparison(comparisonId);
669
+ const group = this.sessionGroupsService.getGroup(comparison.groupId) ?? this.sessionGroupsService.createGroup(comparison.title);
670
+ this._replaceComparison({
671
+ ...comparison,
672
+ groupId: group.id,
673
+ archivedAt: undefined
674
+ });
675
+ return group.id;
676
+ }
677
+ async _startJudge(comparison, judgeParticipantId) {
678
+ const judge = comparison.participants.find(
679
+ participant => participant.id === judgeParticipantId && participant.role === SessionComparisonParticipantRole.Judge
680
+ );
681
+ if (!judge) {
682
+ return;
683
+ }
684
+ const harness = judge.harness;
685
+ const session = await this.sessionsManagementService.createAndSendNewChatRequest(comparison.workspace, {
686
+ query: createSessionComparisonJudgePrompt(comparison.id),
687
+ attachedContext: comparison.attachedContext?.slice(),
688
+ title: ( localize(6322, "Judge: {0}", comparison.title)),
689
+ background: true
690
+ }, {
691
+ providerId: harness.providerId,
692
+ sessionTypeId: harness.sessionTypeId,
693
+ modelId: harness.modelId,
694
+ modelConfiguration: harness.modelConfiguration,
695
+ ...this._permissionOptions(harness, comparison.permissionLevel),
696
+ isolationMode: "worktree",
697
+ branch: comparison.branch,
698
+ metadata: withSessionComparisonMetadata(undefined, {
699
+ id: hashSessionIdForTelemetry(comparison.id),
700
+ role: "judge",
701
+ attemptCount: comparison.participants.filter(
702
+ participant => participant.role === SessionComparisonParticipantRole.Attempt
703
+ ).length
704
+ }),
705
+ onSessionCreated: createdSession => {
706
+ this._updateComparisonParticipant(comparison.id, judgeParticipantId, participant => ({
707
+ ...participant,
708
+ sessionResource: createdSession.resource,
709
+ launchError: undefined
710
+ }));
711
+ }
712
+ });
713
+ const current = this.getComparison(comparison.id);
714
+ if (!current || current.archivedAt !== undefined) {
715
+ if (current) {
716
+ this._replaceComparison({
717
+ ...current,
718
+ participants: current.participants.filter(participant => participant.id !== judgeParticipantId)
719
+ });
720
+ }
721
+ if (session) {
722
+ await this._cancelAndDeleteSessions([session], "orphaned Judge cleanup");
723
+ }
724
+ return;
725
+ }
726
+ if (session) {
727
+ this.sessionGroupsService.addToGroup(session.sessionId, comparison.groupId);
728
+ }
729
+ const updated = {
730
+ ...current,
731
+ participants: current.participants.map(participant => participant.id === judgeParticipantId ? {
732
+ ...participant,
733
+ sessionResource: session?.resource,
734
+ ...(!session ? {
735
+ launchError: ( localize(6323, "The judge session did not start."))
736
+ } : {})
737
+ } : participant)
738
+ };
739
+ this._replaceComparison(updated);
740
+ this._checkComparison(updated);
741
+ }
742
+ async _cancelAndDeleteSessions(sessions, context) {
743
+ const activeSessions = sessions.filter(session => isActiveSessionStatus(session.status.get()));
744
+ const cancellationResults = await Promise.allSettled(
745
+ activeSessions.map(session => this.sessionsManagementService.cancelCurrentRequest(session))
746
+ );
747
+ for (const result of cancellationResults) {
748
+ if (result.status === "rejected") {
749
+ this.logService.error(
750
+ `[SessionComparisonService] Failed to cancel a session during ${context}.`,
751
+ result.reason
752
+ );
753
+ }
754
+ }
755
+ const deletionResults = await Promise.allSettled(
756
+ sessions.map(session => this.sessionsManagementService.deleteSession(session))
757
+ );
758
+ for (const result of deletionResults) {
759
+ if (result.status === "rejected") {
760
+ this.logService.error(
761
+ `[SessionComparisonService] Failed to delete a session during ${context}.`,
762
+ result.reason
763
+ );
764
+ }
765
+ }
766
+ }
767
+ _getSynthesisPlanPrompt(comparison) {
768
+ const plan = comparison.synthesisPlan;
769
+ if (!plan) {
770
+ return "";
771
+ }
772
+ return plan.instructions ? ( localize(6324, "\n\n## Additional synthesis instructions\n{0}", plan.instructions)) : "";
773
+ }
774
+ _getOtherAttemptStrengthsPrompt(comparison) {
775
+ const verdict = comparison.verdict;
776
+ if (!verdict) {
777
+ return "";
778
+ }
779
+ const findings = ( new Map(verdict.attempts.map(attempt => [attempt.participantId, attempt])));
780
+ const attempts = comparison.participants.filter(
781
+ participant => participant.role === SessionComparisonParticipantRole.Attempt
782
+ );
783
+ const strengths = attempts.flatMap((attempt, index) => {
784
+ if (attempt.id === verdict.recommendedParticipantId) {
785
+ return [];
786
+ }
787
+ const finding = findings.get(attempt.id);
788
+ if (!finding) {
789
+ return [];
790
+ }
791
+ const attemptLabel = getSessionComparisonAttemptLabel(attempt, index + 1);
792
+ return finding.notableDifferences.map(strength => strength.trim()).filter(strength => strength.length > 0).map(strength => ({
793
+ attemptLabel,
794
+ strength
795
+ }));
796
+ }).slice(0, SESSION_COMPARISON_MANIFEST_LIST_MAX_ITEMS).map((
797
+ {
798
+ attemptLabel,
799
+ strength
800
+ }
801
+ ) => ( localize(
802
+ 6325,
803
+ "- **{0}**: {1}",
804
+ attemptLabel,
805
+ getBoundedSessionComparisonManifestText(strength)
806
+ )));
807
+ return strengths.length ? ( localize(
808
+ 6326,
809
+ "\n\n## Strong points from other attempts\n{0}",
810
+ strengths.join("\n")
811
+ )) : "";
812
+ }
813
+ _getVerdictRecommendation(comparison) {
814
+ const verdict = comparison.verdict;
815
+ if (!verdict) {
816
+ return localize(
817
+ 6327,
818
+ "No Judge explanation is available; use the selected attempt as the base."
819
+ );
820
+ }
821
+ const attempts = comparison.participants.filter(
822
+ participant => participant.role === SessionComparisonParticipantRole.Attempt
823
+ );
824
+ const winnerIndex = attempts.findIndex(attempt => attempt.id === verdict.recommendedParticipantId);
825
+ const winner = attempts[winnerIndex];
826
+ const winnerLabel = winner ? getSessionComparisonAttemptLabel(winner, winnerIndex + 1) : ( localize(6328, "Winning attempt"));
827
+ if (!verdict.rationale) {
828
+ return `${winnerLabel}\n${verdict.explanation}`;
829
+ }
830
+ return [winnerLabel, ( localize(6329, "Comparison: {0}", verdict.rationale.comparison)), ( localize(6330, "Validation: {0}", verdict.rationale.validation)), ( localize(6331, "Code quality: {0}", verdict.rationale.codeQuality)), ( localize(6332, "Solution: {0}", verdict.rationale.solution))].join("\n");
831
+ }
832
+ _getJudgeHarness(comparison) {
833
+ return comparison.judgeHarness;
834
+ }
835
+ _ensureComparisonGroupMembership(comparisons) {
836
+ for (const comparison of comparisons) {
837
+ if (comparison.archivedAt !== undefined) {
838
+ continue;
839
+ }
840
+ const sessionIds = comparison.participants.map(
841
+ participant => participant.sessionResource ? this.sessionsManagementService.getSession(participant.sessionResource)?.sessionId : undefined
842
+ ).filter(
843
+ sessionId => sessionId !== undefined && !this.sessionGroupsService.getGroupOfSession(sessionId) && !this.sessionGroupsService.isExplicitlyUngrouped(sessionId)
844
+ );
845
+ this.sessionGroupsService.addToGroup(sessionIds, comparison.groupId);
846
+ }
847
+ }
848
+ _archiveComparisonsWithMissingGroups() {
849
+ const comparisons = this._comparisons.get();
850
+ const archivedAt = Date.now();
851
+ let changed = false;
852
+ const updated = comparisons.map(comparison => {
853
+ if (comparison.archivedAt !== undefined || this.sessionGroupsService.getGroup(comparison.groupId)) {
854
+ return comparison;
855
+ }
856
+ changed = true;
857
+ return {
858
+ ...comparison,
859
+ archivedAt
860
+ };
861
+ });
862
+ if (!changed) {
863
+ return;
864
+ }
865
+ this._comparisons.set(updated, undefined);
866
+ this._save();
867
+ this._pruneAttemptTelemetryState(( new Set(
868
+ updated.filter(comparison => comparison.archivedAt === undefined).map(comparison => comparison.id)
869
+ )));
870
+ }
871
+ _archiveFullyArchivedComparisons(comparisons) {
872
+ for (const comparison of comparisons) {
873
+ if (comparison.archivedAt !== undefined) {
874
+ continue;
875
+ }
876
+ const participantResources = comparison.participants.map(participant => participant.sessionResource).filter(resource => resource !== undefined);
877
+ const sessions = participantResources.map(resource => this.sessionsManagementService.getSession(resource)).filter(session => session !== undefined);
878
+ if (sessions.length === 0 || sessions.length !== participantResources.length || ( sessions.some(session => !session.isArchived.get()))) {
879
+ continue;
880
+ }
881
+ this.archiveComparison(comparison.id);
882
+ this.sessionGroupsService.deleteGroup(comparison.groupId);
883
+ }
884
+ }
885
+ _migrateLegacyAttemptTitles(comparisons) {
886
+ for (const comparison of comparisons) {
887
+ const attempts = comparison.participants.filter(
888
+ participant => participant.role === SessionComparisonParticipantRole.Attempt
889
+ );
890
+ for (const [index, participant] of attempts.entries()) {
891
+ const session = participant.sessionResource ? this.sessionsManagementService.getSession(participant.sessionResource) : undefined;
892
+ if (!session || ( this._migratingAttemptTitles.has(session.sessionId)) || ( this._migratedAttemptTitles.has(session.sessionId))) {
893
+ continue;
894
+ }
895
+ const title = getSessionComparisonHarnessLabel(participant);
896
+ const legacyTitle = ( localize(6333, "Attempt {0}: {1}", index + 1, title));
897
+ const permissionTitle = participant.harness.permissionId && participant.harness.permissionId !== "default" && participant.harness.permissionLabel ? ( localize(6334, "{0} · {1}", title, participant.harness.permissionLabel)) : undefined;
898
+ const currentTitle = session.title.get();
899
+ if (currentTitle !== legacyTitle && currentTitle !== permissionTitle && currentTitle !== (permissionTitle ? ( localize(6333, "Attempt {0}: {1}", index + 1, permissionTitle)) : undefined)) {
900
+ continue;
901
+ }
902
+ this._migratingAttemptTitles.add(session.sessionId);
903
+ void this.sessionsManagementService.renameSession(session, title).then(() => {
904
+ this._migratedAttemptTitles.add(session.sessionId);
905
+ }, error => {
906
+ this.logService.warn("[SessionComparisonService] Failed to migrate an attempt title.", error);
907
+ }).finally(() => {
908
+ this._migratingAttemptTitles.delete(session.sessionId);
909
+ });
910
+ }
911
+ }
912
+ }
913
+ _addComparison(comparison) {
914
+ this._indexComparisonSessions(comparison);
915
+ this._comparisons.set([...this._comparisons.get(), comparison], undefined);
916
+ this._save();
917
+ }
918
+ _replaceComparison(comparison) {
919
+ const previous = this.getComparison(comparison.id);
920
+ if (previous) {
921
+ this._unindexComparisonSessions(previous);
922
+ }
923
+ this._indexComparisonSessions(comparison);
924
+ this._comparisons.set(
925
+ this._comparisons.get().map(candidate => candidate.id === comparison.id ? comparison : candidate),
926
+ undefined
927
+ );
928
+ this._save();
929
+ }
930
+ _removeComparison(comparisonId) {
931
+ const comparison = this.getComparison(comparisonId);
932
+ if (comparison) {
933
+ this._unindexComparisonSessions(comparison);
934
+ }
935
+ this._comparisons.set(
936
+ this._comparisons.get().filter(comparison => comparison.id !== comparisonId),
937
+ undefined
938
+ );
939
+ this._save();
940
+ this._pruneAttemptTelemetryState(( new Set(
941
+ this._comparisons.get().filter(comparison => comparison.archivedAt === undefined).map(comparison => comparison.id)
942
+ )));
943
+ }
944
+ _indexComparisonSessions(comparison) {
945
+ for (const participant of comparison.participants) {
946
+ if (participant.sessionResource) {
947
+ this._comparisonIdsBySession.set(( participant.sessionResource.toString()), comparison.id);
948
+ }
949
+ }
950
+ }
951
+ _unindexComparisonSessions(comparison) {
952
+ for (const participant of comparison.participants) {
953
+ if (participant.sessionResource && this._comparisonIdsBySession.get(( participant.sessionResource.toString())) === comparison.id) {
954
+ this._comparisonIdsBySession.delete(( participant.sessionResource.toString()));
955
+ }
956
+ }
957
+ }
958
+ _getComparisonsForSessionChanges(event) {
959
+ const comparisonIds = ( new Set());
960
+ for (const session of [...event.added, ...event.removed, ...event.changed]) {
961
+ const comparisonId = this._comparisonIdsBySession.get(( session.resource.toString()));
962
+ if (comparisonId) {
963
+ comparisonIds.add(comparisonId);
964
+ }
965
+ }
966
+ return [...comparisonIds].flatMap(comparisonId => {
967
+ const comparison = this.getComparison(comparisonId);
968
+ return comparison ? [comparison] : [];
969
+ });
970
+ }
971
+ _markParticipantDeleted(session) {
972
+ const comparison = this.getComparisonForSession(session.resource);
973
+ const participant = comparison?.participants.find(candidate => candidate.sessionResource?.toString() === ( session.resource.toString()));
974
+ if (!comparison || comparison.archivedAt !== undefined || !participant) {
975
+ return;
976
+ }
977
+ const updated = this._updateComparisonParticipant(comparison.id, participant.id, current => ({
978
+ ...current,
979
+ missingSession: undefined,
980
+ launchError: current.launchError ?? getAttemptUnavailableMessage()
981
+ }));
982
+ if (updated) {
983
+ this._checkComparison(updated);
984
+ }
985
+ }
986
+ _reconcileSessionAvailability(comparison, event) {
987
+ const availableResources = ( new Set([...event.added, ...event.changed].map(session => ( session.resource.toString()))));
988
+ const missingResources = ( new Set(event.removed.filter(
989
+ session => !session.isArchived.get() && !this.sessionsManagementService.getSession(session.resource)
990
+ ).map(session => ( session.resource.toString()))));
991
+ let changed = false;
992
+ const participants = comparison.participants.map(participant => {
993
+ const resource = participant.sessionResource?.toString();
994
+ if (!resource) {
995
+ return participant;
996
+ }
997
+ if (participant.missingSession && ( availableResources.has(resource))) {
998
+ changed = true;
999
+ return {
1000
+ ...participant,
1001
+ missingSession: undefined,
1002
+ launchError: undefined
1003
+ };
1004
+ }
1005
+ if (!participant.launchError && ( missingResources.has(resource))) {
1006
+ changed = true;
1007
+ return {
1008
+ ...participant,
1009
+ missingSession: true,
1010
+ launchError: getAttemptUnavailableMessage()
1011
+ };
1012
+ }
1013
+ return participant;
1014
+ });
1015
+ if (!changed) {
1016
+ return comparison;
1017
+ }
1018
+ const updated = {
1019
+ ...comparison,
1020
+ participants
1021
+ };
1022
+ this._replaceComparison(updated);
1023
+ return updated;
1024
+ }
1025
+ _load() {
1026
+ const raw = this.storageService.get(SessionComparisonService_1.STORAGE_KEY, StorageScope.PROFILE);
1027
+ if (!raw) {
1028
+ return [];
1029
+ }
1030
+ try {
1031
+ const stored = parse(raw);
1032
+ return stored.map(comparison => ({
1033
+ ...comparison,
1034
+ judgeHarness: comparison.judgeHarness ?? (comparison.version === undefined ? comparison.participants.find(
1035
+ participant => participant.role === SessionComparisonParticipantRole.Coordinator
1036
+ )?.harness ?? comparison.participants.find(
1037
+ participant => participant.role === SessionComparisonParticipantRole.Attempt && participant.sessionResource
1038
+ )?.harness : undefined),
1039
+ synthesisPlan: comparison.synthesisPlan?.instructions ? {
1040
+ instructions: comparison.synthesisPlan.instructions
1041
+ } : undefined,
1042
+ verdict: comparison.verdict ? {
1043
+ recommendedParticipantId: comparison.verdict.recommendedParticipantId,
1044
+ explanation: comparison.verdict.explanation,
1045
+ rationale: comparison.verdict.rationale,
1046
+ conflicts: comparison.verdict.conflicts,
1047
+ attempts: comparison.verdict.attempts
1048
+ } : undefined,
1049
+ launching: undefined,
1050
+ workspace: ( URI.parse(comparison.workspace)),
1051
+ attachedContext: comparison.attachedContext?.map(IChatRequestVariableEntry.fromExport),
1052
+ participants: comparison.participants.map(participant => ({
1053
+ ...participant,
1054
+ sessionResource: participant.sessionResource ? ( URI.parse(participant.sessionResource)) : undefined,
1055
+ ...(comparison.launching && participant.role === SessionComparisonParticipantRole.Attempt && !participant.sessionResource && !participant.launchError ? {
1056
+ launchError: ( localize(6335, "The attempt was interrupted before it started."))
1057
+ } : {})
1058
+ }))
1059
+ }));
1060
+ } catch (error) {
1061
+ this.logService.error("[SessionComparisonService] Failed to restore comparisons.", error);
1062
+ return [];
1063
+ }
1064
+ }
1065
+ _save() {
1066
+ const stored = this._comparisons.get().map(comparison => ({
1067
+ ...comparison,
1068
+ version: 1,
1069
+ workspace: ( comparison.workspace.toString()),
1070
+ attachedContext: comparison.attachedContext?.map(IChatRequestVariableEntry.toExport),
1071
+ participants: comparison.participants.map(participant => ({
1072
+ ...participant,
1073
+ sessionResource: participant.sessionResource?.toString()
1074
+ }))
1075
+ }));
1076
+ this.storageService.store(
1077
+ SessionComparisonService_1.STORAGE_KEY,
1078
+ stringify(stored),
1079
+ StorageScope.PROFILE,
1080
+ StorageTarget.MACHINE
1081
+ );
1082
+ }
1083
+ _loadAttemptTelemetryState() {
1084
+ const raw = this.storageService.get(
1085
+ SessionComparisonService_1.ATTEMPT_TELEMETRY_STORAGE_KEY,
1086
+ StorageScope.PROFILE
1087
+ );
1088
+ if (!raw) {
1089
+ return;
1090
+ }
1091
+ try {
1092
+ const keys = JSON.parse(raw);
1093
+ for (const key of keys) {
1094
+ this._reportedAttemptTelemetry.add(key);
1095
+ }
1096
+ } catch (error) {
1097
+ this.logService.error(
1098
+ "[SessionComparisonService] Failed to restore comparison attempt telemetry state.",
1099
+ error
1100
+ );
1101
+ }
1102
+ }
1103
+ _saveAttemptTelemetryState() {
1104
+ this.storageService.store(
1105
+ SessionComparisonService_1.ATTEMPT_TELEMETRY_STORAGE_KEY,
1106
+ JSON.stringify([...this._reportedAttemptTelemetry]),
1107
+ StorageScope.PROFILE,
1108
+ StorageTarget.MACHINE
1109
+ );
1110
+ }
1111
+ _pruneAttemptTelemetryState(comparisonIds) {
1112
+ let changed = false;
1113
+ for (const key of [...this._reportedAttemptTelemetry]) {
1114
+ const separator = key.indexOf("/");
1115
+ if (separator < 0 || !( comparisonIds.has(key.slice(0, separator)))) {
1116
+ this._reportedAttemptTelemetry.delete(key);
1117
+ changed = true;
1118
+ }
1119
+ }
1120
+ if (changed) {
1121
+ this._saveAttemptTelemetryState();
1122
+ }
1123
+ }
1124
+ };
1125
+ SessionComparisonService = SessionComparisonService_1 = ( __decorate([( __param(0, ISessionsManagementService)), ( __param(1, ISessionGroupsService)), ( __param(2, IStorageService)), ( __param(3, ILogService)), ( __param(4, IChatService)), ( __param(5, ITelemetryService))], SessionComparisonService));
1126
+ function snapshotAttachedContext(attachedContext) {
1127
+ const stored = attachedContext.map(IChatRequestVariableEntry.toExport);
1128
+ return parse(stringify(stored)).map(IChatRequestVariableEntry.fromExport);
1129
+ }
1130
+ function comparisonTitle(prompt) {
1131
+ const firstLine = prompt.trim().split(/\r?\n/, 1)[0];
1132
+ return firstLine.length > 60 ? `${firstLine.slice(0, 57)}...` : firstLine;
1133
+ }
1134
+
1135
+ export { SessionComparisonService };