|
6 | 6 | import vscode from 'vscode'; |
7 | 7 | import { parseSessionLogs, parseToolCallDetails } from '../../common/sessionParsing'; |
8 | 8 | import { Repository } from '../api/api'; |
| 9 | +import { COPILOT_ACCOUNTS } from '../common/comment'; |
9 | 10 | import { COPILOT_LOGINS, copilotEventToStatus, CopilotPRStatus, mostRecentCopilotEvent } from '../common/copilot'; |
10 | 11 | import { commands } from '../common/executeCommands'; |
11 | 12 | import { Disposable } from '../common/lifecycle'; |
@@ -41,6 +42,15 @@ export interface ICopilotRemoteAgentCommandArgs { |
41 | 42 | summary?: string; |
42 | 43 | source?: string; |
43 | 44 | followup?: string; |
| 45 | + _version?: number; // TODO(jospicer): Remove once stabilized/engine version enforced |
| 46 | +} |
| 47 | + |
| 48 | +export interface ICopilotRemoteAgentCommandResponse { |
| 49 | + uri: string; |
| 50 | + title: string; |
| 51 | + description: string; |
| 52 | + author: string; |
| 53 | + linkTag: string; |
44 | 54 | } |
45 | 55 |
|
46 | 56 | const LEARN_MORE = vscode.l10n.t('Learn about coding agent'); |
@@ -230,33 +240,6 @@ export class CopilotRemoteAgentManager extends Disposable { |
230 | 240 | return { owner, repo, baseRef, remote, repository, ghRepository, fm }; |
231 | 241 | } |
232 | 242 |
|
233 | | - private parseFollowup(followup: string | undefined, repoInfo: { owner: string; repo: string }): number | undefined { |
234 | | - if (!followup) { |
235 | | - return; |
236 | | - } |
237 | | - const match = followup.match(FOLLOW_UP_REGEX); |
238 | | - if (!match || match.length < 2) { |
239 | | - Logger.error(`Ignoring. Invalid followup format: ${followup}`, CopilotRemoteAgentManager.ID); |
240 | | - return; |
241 | | - } |
242 | | - |
243 | | - try { |
244 | | - const followUpData = JSON.parse(decodeURIComponent(match[1])); |
245 | | - if (!followUpData || !followUpData.owner || !followUpData.repo || !followUpData.pullRequestNumber) { |
246 | | - Logger.error(`Ignoring. Invalid followup data: ${followUpData}`, CopilotRemoteAgentManager.ID); |
247 | | - return; |
248 | | - } |
249 | | - |
250 | | - if (repoInfo.owner !== followUpData.owner || repoInfo.repo !== followUpData.repo) { |
251 | | - Logger.error(`Ignoring. Follow up data does not match current repository: ${JSON.stringify(followUpData)}`, CopilotRemoteAgentManager.ID); |
252 | | - return; |
253 | | - } |
254 | | - return followUpData.pullRequestNumber; |
255 | | - } catch (error) { |
256 | | - Logger.error(`Ignoring. Error while parsing follow up data: ${followup}`, CopilotRemoteAgentManager.ID); |
257 | | - } |
258 | | - } |
259 | | - |
260 | 243 | async addFollowUpToExistingPR(pullRequestNumber: number, userPrompt: string, summary?: string): Promise<string | undefined> { |
261 | 244 | const repoInfo = await this.repoInfo(); |
262 | 245 | if (!repoInfo) { |
@@ -285,25 +268,27 @@ export class CopilotRemoteAgentManager extends Disposable { |
285 | 268 | } |
286 | 269 | } |
287 | 270 |
|
288 | | - async commandImpl(args?: ICopilotRemoteAgentCommandArgs): Promise<string | undefined> { |
| 271 | + async commandImpl(args?: ICopilotRemoteAgentCommandArgs): Promise<string | ICopilotRemoteAgentCommandResponse | undefined> { |
289 | 272 | if (!args) { |
290 | 273 | return; |
291 | 274 | } |
292 | | - const { userPrompt, summary, source, followup } = args; |
| 275 | + const { userPrompt, summary, source, followup, _version } = args; |
293 | 276 |
|
294 | 277 | /* __GDPR__ |
295 | 278 | "remoteAgent.command.args" : { |
296 | 279 | "source" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, |
297 | 280 | "isFollowup" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, |
298 | 281 | "userPromptLength" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, |
299 | | - "summaryLength" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } |
| 282 | + "summaryLength" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, |
| 283 | + "version" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } |
300 | 284 | } |
301 | 285 | */ |
302 | 286 | this.telemetry.sendTelemetryEvent('remoteAgent.command.args', { |
303 | 287 | source: source?.toString() || 'unknown', |
304 | 288 | isFollowup: !!followup ? 'true' : 'false', |
305 | 289 | userPromptLength: userPrompt.length.toString(), |
306 | | - summaryLength: summary ? summary.length.toString() : '0' |
| 290 | + summaryLength: summary ? summary.length.toString() : '0', |
| 291 | + version: _version?.toString() || 'unknown' |
307 | 292 | }); |
308 | 293 |
|
309 | 294 | if (!userPrompt || userPrompt.trim().length === 0) { |
@@ -416,25 +401,34 @@ export class CopilotRemoteAgentManager extends Disposable { |
416 | 401 |
|
417 | 402 | this._onDidChangeChatSessions.fire(); |
418 | 403 | const viewLocationSetting = vscode.workspace.getConfiguration('chat').get('agentSessionsViewLocation'); |
419 | | - |
420 | | - if (!viewLocationSetting || viewLocationSetting === 'disabled') { |
421 | | - vscode.commands.executeCommand('vscode.open', webviewUri); |
422 | | - } else { |
423 | | - await this.provideChatSessions(new vscode.CancellationTokenSource().token); |
424 | | - |
| 404 | + const pr = await (async () => { |
425 | 405 | const capi = await this.copilotApi; |
426 | 406 | if (!capi) { |
427 | 407 | return; |
428 | 408 | } |
429 | | - |
430 | 409 | const sessions = await capi.getAllCodingAgentPRs(this.repositoriesManager); |
431 | | - const pr = sessions.find(session => session.number === number); |
| 410 | + return sessions.find(session => session.number === number); |
| 411 | + })(); |
432 | 412 |
|
| 413 | + if (!viewLocationSetting || viewLocationSetting === 'disabled') { |
| 414 | + vscode.commands.executeCommand('vscode.open', webviewUri); |
| 415 | + } else { |
| 416 | + await this.provideChatSessions(new vscode.CancellationTokenSource().token); |
433 | 417 | if (pr) { |
434 | 418 | vscode.window.showChatSession('copilot-swe-agent', `${pr.id}`, {}); |
435 | 419 | } |
436 | 420 | } |
437 | 421 |
|
| 422 | + if (pr && (_version && _version === 2)) { /* version 2 means caller knows how to render this */ |
| 423 | + return { |
| 424 | + uri: webviewUri.toString(), |
| 425 | + title: pr.title, |
| 426 | + description: pr.body, |
| 427 | + author: COPILOT_ACCOUNTS[pr.author.login].name, |
| 428 | + linkTag: `#${pr.number}` |
| 429 | + }; |
| 430 | + } |
| 431 | + |
438 | 432 | // allow-any-unicode-next-line |
439 | 433 | return vscode.l10n.t('🚀 Coding agent will continue work in [#{0}]({1}). Track progress [here]({2}).', number, link, webviewUri.toString()); |
440 | 434 | } |
|
0 commit comments