|
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