Skip to content

Commit a5381eb

Browse files
authored
Merge pull request #88 from devverseio/fix/reviews
Fix/reviews
2 parents 7d652d7 + 8004d82 commit a5381eb

File tree

13 files changed

+65
-29
lines changed

13 files changed

+65
-29
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"cSpell.words": [
8282
"brotli",
8383
"Chinmaya",
84+
"commitable",
8485
"commitlint",
8586
"consts",
8687
"drgit",

bun.lockb

40 Bytes
Binary file not shown.

src/common/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export * from './diff-line.type';
66
export * from './diff-position.type';
77
export * from './file-content.type';
88
export * from './file-context.type';
9+
export * from './review-object.type';
910
export * from './summary-object.type';
1011
export * from './template-replacement.type';
1112
export * from './walkthrough-object.type';
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { z } from 'zod';
2+
import { reviewObjectSchema } from '~schemas';
3+
4+
export type ReviewObject = z.infer<typeof reviewObjectSchema>;

src/handlers/review.handler.ts

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import { generateText } from 'ai';
1+
import { generateObject } from 'ai';
22
import { Context } from 'probot';
33
import { profileDetails, toneDetails } from '~common/consts';
44
import { Severity } from '~common/enums';
55
import { Handler } from '~common/interfaces';
6-
import { CombinedLineGroup, Config, DiffLine, DiffPosition } from '~common/types';
6+
import { CombinedLineGroup, Config, DiffLine, DiffPosition, ReviewObject } from '~common/types';
77
import { aiConfig } from '~configs';
88
import { SystemError } from '~errors';
99
import { cleanDiffString } from '~helpers';
10+
import { reviewObjectSchema } from '~schemas';
1011
import { AiService, CacheService, GitHubService, QueueService, TemplateService } from '~services';
11-
import { reviewPromptTemplate, reviewSystemTemplate } from '~templates';
12+
import { reviewCommentTemplate, reviewPromptTemplate, reviewSystemTemplate } from '~templates';
1213
import { ReviewSkipConditions } from '~utils';
1314

1415
export class ReviewHandler implements Handler<'pull_request'> {
@@ -30,18 +31,30 @@ export class ReviewHandler implements Handler<'pull_request'> {
3031

3132
await Promise.all(
3233
fileContents.flatMap((file) => {
33-
const combinedDiff = diffPositions.find((diffFile) => diffFile?.path === file.name)?.positions;
34+
const combinedDiff = diffPositions.find((diffFile) => diffFile.path === file.name)?.positions;
3435

3536
if (combinedDiff) {
36-
return Promise.all(
37-
combinedDiff.map(async (diff) => {
38-
const result = await this.generateReport(apiKey, config, file.content, diff.content);
39-
40-
return this.queueService.schedule(() =>
41-
GitHubService.createInlineReviewComment(context, result, file.name, diff.endDiffPosition)
42-
);
43-
})
44-
);
37+
return combinedDiff.map(async (diff) => {
38+
const { commitableSuggestion, review, shouldReview } = await this.generateReport(
39+
apiKey,
40+
config,
41+
file.content,
42+
diff.content
43+
);
44+
45+
if (!shouldReview) {
46+
return null;
47+
}
48+
49+
const comment = TemplateService.render(reviewCommentTemplate, {
50+
review,
51+
commitableSuggestion
52+
});
53+
54+
return this.queueService.schedule(() =>
55+
GitHubService.createInlineReviewComment(context, comment, file.name, diff.endDiffPosition)
56+
);
57+
});
4558
}
4659

4760
return [];
@@ -141,7 +154,7 @@ export class ReviewHandler implements Handler<'pull_request'> {
141154
return result;
142155
}
143156

144-
private async generateReport(apiKey: string, config: Config, content: string, diff: string): Promise<string> {
157+
private async generateReport(apiKey: string, config: Config, content: string, diff: string): Promise<ReviewObject> {
145158
const prompt = TemplateService.render(reviewPromptTemplate, {
146159
content,
147160
diff: cleanDiffString(diff)
@@ -154,14 +167,15 @@ export class ReviewHandler implements Handler<'pull_request'> {
154167

155168
return this.queueService.schedule(async () => {
156169
try {
157-
const result = await generateText({
170+
const result = await generateObject<ReviewObject>({
158171
model: this.aiService.getModel(aiConfig.model.incrementalReview, apiKey),
159172
topP: aiConfig.topP.review,
160173
system,
161-
prompt
174+
prompt,
175+
schema: reviewObjectSchema
162176
});
163177

164-
return result.text;
178+
return result.object;
165179
} catch (error) {
166180
throw new SystemError('Failed to generate review', Severity.ERROR, error);
167181
}

src/handlers/summary.handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export class SummaryHandler implements Handler<'pull_request'> {
8888
const result = await this.queueService.schedule(() =>
8989
generateObject<SummaryObject>({
9090
topP: aiConfig.topP.summary,
91-
model: this.aiService.getModel(aiConfig.model.summary, apiKey, true),
91+
model: this.aiService.getModel(aiConfig.model.summary, apiKey),
9292
system: TemplateService.render(summarySystemTemplate, {
9393
tone: toneDetails[config.summary.tone],
9494
language: config.language

src/handlers/walkthrough.handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export class WalkthroughHandler implements Handler<'pull_request'> {
8080
const result = await this.queueService.schedule(() =>
8181
generateObject<WalkthroughObject>({
8282
topP: aiConfig.topP.walkthrough,
83-
model: this.aiService.getModel(aiConfig.model.walkthrough, apiKey, true),
83+
model: this.aiService.getModel(aiConfig.model.walkthrough, apiKey),
8484
system: TemplateService.render(walkthroughSystemTemplate, {
8585
tone: toneDetails[config.walkthrough.tone],
8686
language: config.language

src/schemas/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './config.schema';
2+
export * from './review-object.schema';
23
export * from './summary-object.schema';
34
export * from './walkthrough-object.schema';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { z } from 'zod';
2+
3+
export const reviewObjectSchema = z.object({
4+
shouldReview: z.boolean().describe('Whether the review should be done or not'),
5+
review: z.string().describe('The review generated if shouldReview is true'),
6+
commitableSuggestion: z.string()
7+
.describe(`The commitable suggestion generated if shouldReview is true. Make sure to use suggestion block like this:
8+
\`\`\`suggestion
9+
<...>
10+
<...>
11+
<...>
12+
<...>
13+
\`\`\`
14+
`)
15+
});

src/services/ai.service.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ export class AiService {
1919
return AiService.instance;
2020
}
2121

22-
public getModel(model: SupportedModel, apiKey: string, structuredOutputs: boolean = false): LanguageModelV1 {
22+
public getModel(model: SupportedModel, apiKey: string): LanguageModelV1 {
2323
return this.provider(model, {
2424
logprobs: false,
25-
user: hashSha256(apiKey),
26-
structuredOutputs
25+
user: hashSha256(apiKey)
2726
});
2827
}
2928

0 commit comments

Comments
 (0)