Skip to content

Commit f3998a6

Browse files
committed
Sends PR/issue/autolink context to review mode input
Adds context to all review mode prompts. Gathers cached-only PR/issue/autolink context based on the review entrypoint, and passes into the prompt to help the agent understant intent behind changes. Goal is to improve review quality.
1 parent 3973bc5 commit f3998a6

9 files changed

Lines changed: 525 additions & 20 deletions

File tree

packages/plus/ai/src/models/promptTemplates.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,14 @@ interface ReviewPullRequestPromptTemplateContext {
8181
interface ReviewChangesPromptTemplateContext {
8282
diff: string;
8383
message: string;
84+
context?: string;
8485
instructions?: string;
8586
}
8687

8788
interface ReviewOverviewPromptTemplateContext {
8889
files: string;
8990
message: string;
91+
context?: string;
9092
instructions?: string;
9193
}
9294

@@ -95,6 +97,7 @@ interface ReviewDetailPromptTemplateContext {
9597
overview: string;
9698
message: string;
9799
focusArea: string;
100+
context?: string;
98101
instructions?: string;
99102
}
100103

packages/plus/ai/src/prompts.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ Now, proceed with your analysis and provide a comprehensive review of the PR. Re
529529

530530
export const reviewChanges: PromptTemplate<'review-changes'> = {
531531
id: 'review-changes',
532-
variables: ['diff', 'message', 'instructions'],
532+
variables: ['diff', 'message', 'context', 'instructions'],
533533
template: `You are an expert code reviewer analyzing a set of code changes. Your goal is to identify meaningful issues — bugs, logic errors, security vulnerabilities, missing error handling, and potential regressions — while ignoring style preferences and linter-level concerns. Focus on problems a careful human reviewer would catch.
534534
535535
Examine the following code changes in Git diff format. Each non-header line inside a hunk has been annotated with its 1-based new-file line number in a \`[NNNNN]\` block placed immediately after the line-type marker (\` \`, \`+\`, or \`-\`):
@@ -546,6 +546,9 @@ Author's description of the changes:
546546
\${message}
547547
</~~message~~>
548548
549+
Related work items (known pull requests and issues for this change set). Use these for *intent*: what the change is trying to accomplish. They are not authoritative spec — if a finding contradicts the stated intent, flag it rather than defer to it. May be empty.
550+
\${context}
551+
549552
Produce a structured review in the following XML format. Include ONLY the XML tags described — no other text:
550553
551554
<overview>
@@ -580,7 +583,7 @@ Review the changes and produce the structured XML output above.`,
580583

581584
export const reviewOverview: PromptTemplate<'review-overview'> = {
582585
id: 'review-overview',
583-
variables: ['files', 'message', 'instructions'],
586+
variables: ['files', 'message', 'context', 'instructions'],
584587
template: `You are an expert code reviewer performing an initial assessment of a set of code changes. You are given a file manifest (not full diffs) — use the file paths, change types, and line counts to identify which areas deserve closer inspection.
585588
586589
File manifest (JSON array of changed files):
@@ -593,6 +596,9 @@ Author's description of the changes:
593596
\${message}
594597
</~~message~~>
595598
599+
Related work items (known pull requests and issues for this change set). Use these for *intent* — what the change is trying to accomplish — when ranking which areas deserve closer review. May be empty.
600+
\${context}
601+
596602
Produce a structured assessment in the following XML format. Include ONLY the XML tags described — no other text:
597603
598604
<overview>
@@ -619,7 +625,7 @@ Assess the changes and produce the structured XML output above.`,
619625

620626
export const reviewDetail: PromptTemplate<'review-detail'> = {
621627
id: 'review-detail',
622-
variables: ['diff', 'overview', 'message', 'focusArea', 'instructions'],
628+
variables: ['diff', 'overview', 'message', 'focusArea', 'context', 'instructions'],
623629
template: `You are an expert code reviewer performing a detailed inspection of specific files that were flagged for closer review. You have the context from an initial overview assessment.
624630
625631
Initial overview of the full changeset:
@@ -634,6 +640,9 @@ Author's description of the changes:
634640
\${message}
635641
</~~message~~>
636642
643+
Related work items (known pull requests and issues for this change set). Use these for *intent* — what the change is trying to accomplish. They are not authoritative spec; if a finding contradicts the stated intent, flag it. May be empty.
644+
\${context}
645+
637646
Code changes for the files in this focus area (Git diff format). Each non-header line inside a hunk has been annotated with its 1-based new-file line number in a \`[NNNNN]\` block placed immediately after the line-type marker (\` \`, \`+\`, or \`-\`):
638647
\` [ 42] context line\` // context: exists in both old and new; number = new-file line
639648
\`+[ 43] added line\` // added: only in new file; number = new-file line

src/autolinks/autolinksProvider.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,12 @@ export class AutolinksProvider implements Disposable {
189189
getEnrichedAutolinks(
190190
message: string,
191191
remote: GitRemote | undefined,
192+
options?: { cached?: boolean },
192193
): Promise<Map<string, EnrichedAutolink> | undefined>;
193194
getEnrichedAutolinks(
194195
autolinks: Map<string, Autolink>,
195196
remote: GitRemote | undefined,
197+
options?: { cached?: boolean },
196198
): Promise<Map<string, EnrichedAutolink> | undefined>;
197199
@trace({
198200
args: (messageOrAutolinks, remote) => ({
@@ -204,12 +206,16 @@ export class AutolinksProvider implements Disposable {
204206
getEnrichedAutolinks(
205207
messageOrAutolinks: string | Map<string, Autolink>,
206208
remote: GitRemote | undefined,
209+
options?: { cached?: boolean },
207210
): Promise<Map<string, EnrichedAutolink> | undefined> {
208211
const remoteKey = remote?.remoteKey ?? '';
209212
const key =
210213
typeof messageOrAutolinks === 'string'
211214
? `m:${remoteKey}:${messageOrAutolinks}`
212215
: `a:${remoteKey}:${[...messageOrAutolinks.keys()].sort().join('|')}`;
216+
if (options?.cached) {
217+
return this._inflightEnrichmentCache.get(key) ?? Promise.resolve(undefined);
218+
}
213219
return this._inflightEnrichmentCache.getOrCreate(key, () =>
214220
this.enrichAutolinksCore(messageOrAutolinks, remote),
215221
);

src/cache.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,32 @@ export class CacheProvider implements Disposable {
250250
return this.get('defaultBranch', `repo:${key}`, etag, cacheable, options);
251251
}
252252

253+
peekPullRequestForBranch(
254+
branch: string,
255+
repo: ResourceDescriptor,
256+
integration: GitHostIntegration | undefined,
257+
): PullRequest | undefined {
258+
const { key } = this.getResourceKeyAndEtag(repo, integration);
259+
return this.peek('prByBranch', `branch:${branch}:${key}`);
260+
}
261+
262+
peekPullRequestForSha(
263+
sha: string,
264+
repo: ResourceDescriptor,
265+
integration: GitHostIntegration | undefined,
266+
): PullRequest | undefined {
267+
const { key } = this.getResourceKeyAndEtag(repo, integration);
268+
return this.peek('prsBySha', `sha:${sha}:${key}`);
269+
}
270+
271+
peekIssue(id: string, resource: ResourceDescriptor, integration: IntegrationBase | undefined): Issue | undefined {
272+
const { key } = this.getResourceKeyAndEtag(resource, integration);
273+
return this.peek(
274+
'issuesByIdAndResource',
275+
`id:${id}:${key}:${'issue' satisfies IssueOrPullRequestType}:${JSON.stringify(resource)}}`,
276+
);
277+
}
278+
253279
getRepositoryMetadata(
254280
repo: ResourceDescriptor,
255281
integration: GitHostIntegration | undefined,

src/git/utils/-webview/branch.issue.utils.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export async function getAssociatedIssuesForBranch(
4747
options?: {
4848
cancellation?: AbortSignal;
4949
timeout?: number;
50+
/** Only return issues already in the local cache. No remote fetch — uncached entries are skipped. */
51+
cached?: boolean;
5052
},
5153
): Promise<MaybePausedResult<Issue[] | undefined>> {
5254
const { encoded } = await getConfigKeyAndEncodedAssociatedIssuesForBranch(container, branch);
@@ -66,7 +68,9 @@ export async function getAssociatedIssuesForBranch(
6668
(async () => {
6769
return (
6870
await Promise.allSettled(
69-
(associatedIssues ?? []).map(i => getIssueFromGitConfigEntityIdentifier(container, i)),
71+
(associatedIssues ?? []).map(i =>
72+
getIssueFromGitConfigEntityIdentifier(container, i, { cached: options?.cached }),
73+
),
7074
)
7175
)
7276
.map(r => getSettledValue(r))

src/git/utils/-webview/branch.utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,27 @@ export async function getBranchAssociatedPullRequest(
219219
avatarSize?: number;
220220
include?: PullRequestState[];
221221
expiryOverride?: boolean | number;
222+
/** Only return a value already in the local cache. No remote fetch — returns undefined on cache miss. */
223+
cached?: boolean;
222224
},
223225
): Promise<PullRequest | undefined> {
224226
const remote = await getBranchRemote(container, branch);
225227
if (remote?.provider == null) return undefined;
226228

227229
const integration = await getRemoteIntegration(remote);
230+
231+
if (options?.cached) {
232+
if (branch.upstream?.missing) {
233+
if (!branch.sha) return undefined;
234+
return container.cache.peekPullRequestForSha(branch.sha, remote.provider.repoDesc, integration);
235+
}
236+
return container.cache.peekPullRequestForBranch(
237+
branch.trackingWithoutRemote ?? branch.nameWithoutRemote,
238+
remote.provider.repoDesc,
239+
integration,
240+
);
241+
}
242+
228243
if (integration == null) return undefined;
229244

230245
if (branch.upstream?.missing) {

0 commit comments

Comments
 (0)