1
1
import { writeFile } from 'node:fs/promises' ;
2
2
import chalk from 'chalk' ;
3
- import { stepCountIs , type LanguageModel , type ModelMessage } from 'ai' ;
3
+ import { stepCountIs , streamText , type LanguageModel , type ModelMessage } from 'ai' ;
4
4
import type { CodeReviewOptions , CodeReviewResult } from '../types' ;
5
5
import {
6
- getUserPrompt ,
7
- getSystemPrompt ,
8
- getApprovalCheckPrompt ,
9
- getApprovalCheckStatusPrompt ,
6
+ getReviewReportMessages ,
7
+ getApprovalCheckCommentMessages ,
8
+ getApprovalCheckStatusMessages ,
10
9
} from './prompts/index' ;
11
10
import { runCmd } from './utils' ;
12
11
import { reviewReportTools } from './tools' ;
13
- import { initModel , callModel } from './model' ;
12
+ import { initModel , handleStreamTextResult } from './model' ;
14
13
15
14
export async function codeReview ( options : CodeReviewOptions ) : Promise < CodeReviewResult > {
16
15
// init model
@@ -22,8 +21,8 @@ export async function codeReview(options: CodeReviewOptions): Promise<CodeReview
22
21
model,
23
22
} ) ;
24
23
25
- // generate approval check
26
- const approvalCheck = options . approvalCheck
24
+ // generate approval check comment
25
+ const approvalCheckComment = options . approvalCheck
27
26
? await generateApprovalCheck ( {
28
27
...options ,
29
28
model,
@@ -33,30 +32,22 @@ export async function codeReview(options: CodeReviewOptions): Promise<CodeReview
33
32
34
33
// generate approval check status
35
34
const approvalCheckStatus =
36
- options . approvalCheck && approvalCheck
35
+ options . approvalCheck && approvalCheckComment
37
36
? await generateApprovalCheckStatus ( {
38
37
...options ,
39
38
model,
40
- prevMessages : approvalCheck . messages ,
39
+ prevMessages : approvalCheckComment . messages ,
41
40
} )
42
41
: undefined ;
43
42
44
43
// return
45
44
return {
46
- content : reviewReport . text ,
47
- reasoningContent : reviewReport . reasoning ,
48
- debug : {
49
- diffsCmd : reviewReport . diffsCmd ,
50
- diffs : reviewReport . diffs ,
51
- stats : reviewReport . stats ,
52
- usage : reviewReport . usage ,
53
- } ,
45
+ reviewReport,
54
46
approvalCheck :
55
- approvalCheck && approvalCheckStatus
47
+ approvalCheckComment && approvalCheckStatus
56
48
? {
57
- content : approvalCheck . text ,
58
- reasoningContent : approvalCheck . reasoning ,
59
- approved : approvalCheckStatus . approved ,
49
+ approvalCheckComment,
50
+ approvalCheckStatus,
60
51
}
61
52
: undefined ,
62
53
} ;
@@ -100,29 +91,32 @@ async function generateReviewReport(
100
91
}
101
92
const diffs = await runCmd ( 'git' , diffArgs ) ;
102
93
103
- // generate review report
104
- const result = await callModel ( {
94
+ // messages
95
+ const messages = await getReviewReportMessages ( {
96
+ systemPromptFile,
97
+ promptFile,
98
+ disableTools,
99
+ diffs,
100
+ baseRef,
101
+ headRef,
102
+ } ) ;
103
+
104
+ // call model
105
+ const result = await handleStreamTextResult ( {
105
106
title : 'Review Report' ,
106
- model,
107
- tools : disableTools ? undefined : reviewReportTools ,
108
- stopWhen : stepCountIs ( maxSteps ) ,
109
- messages : [
110
- {
111
- role : 'system' ,
112
- content : await getSystemPrompt ( {
113
- systemPromptFile,
114
- disableTools,
115
- diffs,
116
- baseRef,
117
- headRef,
118
- } ) ,
119
- } ,
120
- { role : 'user' , content : await getUserPrompt ( promptFile ) } ,
121
- ] ,
122
107
print,
123
- temperature,
124
- topP,
125
- topK,
108
+ streamTextResult : streamText ( {
109
+ model,
110
+ messages,
111
+ tools : disableTools ? undefined : reviewReportTools ,
112
+ stopWhen : stepCountIs ( maxSteps ) ,
113
+ temperature,
114
+ topP,
115
+ topK,
116
+ onError : ( { error } ) => {
117
+ throw new Error ( 'failed to call the model' , { cause : error } ) ;
118
+ } ,
119
+ } ) ,
126
120
} ) ;
127
121
128
122
// write output file
@@ -133,6 +127,7 @@ async function generateReviewReport(
133
127
// return
134
128
return {
135
129
...result ,
130
+ messages : [ ...messages , ...result . messages ] ,
136
131
diffsCmd,
137
132
diffs,
138
133
} ;
@@ -147,26 +142,32 @@ async function generateApprovalCheck(
147
142
// options
148
143
const { model, prevMessages, approvalCheck, print, temperature, topP, topK } = options ;
149
144
150
- // generate approval check
151
- const result = await callModel ( {
152
- title : 'Approval Check' ,
153
- model,
154
- messages : [
155
- ...prevMessages ,
156
- {
157
- role : 'user' ,
158
- content : await getApprovalCheckPrompt ( approvalCheck ) ,
159
- } ,
160
- ] ,
145
+ // messages
146
+ const messages = await getApprovalCheckCommentMessages ( {
147
+ prevMessages,
148
+ approvalCheck,
149
+ } ) ;
150
+
151
+ // call model
152
+ const result = await handleStreamTextResult ( {
153
+ title : 'Approval Check Comment' ,
161
154
print,
162
- temperature,
163
- topP,
164
- topK,
155
+ streamTextResult : streamText ( {
156
+ model,
157
+ messages,
158
+ temperature,
159
+ topP,
160
+ topK,
161
+ onError : ( { error } ) => {
162
+ throw new Error ( 'failed to call the model' , { cause : error } ) ;
163
+ } ,
164
+ } ) ,
165
165
} ) ;
166
166
167
167
// return
168
168
return {
169
169
...result ,
170
+ messages : [ ...messages , ...result . messages ] ,
170
171
} ;
171
172
}
172
173
@@ -179,21 +180,23 @@ async function generateApprovalCheckStatus(
179
180
// options
180
181
const { model, prevMessages, print, temperature, topP, topK } = options ;
181
182
182
- // generate approval check
183
- const result = await callModel ( {
183
+ // messages
184
+ const messages = getApprovalCheckStatusMessages ( { prevMessages } ) ;
185
+
186
+ // call model
187
+ const result = await handleStreamTextResult ( {
184
188
title : 'Approval Check Status' ,
185
- model,
186
- messages : [
187
- ...prevMessages ,
188
- {
189
- role : 'user' ,
190
- content : await getApprovalCheckStatusPrompt ( ) ,
191
- } ,
192
- ] ,
193
189
print,
194
- temperature,
195
- topP,
196
- topK,
190
+ streamTextResult : streamText ( {
191
+ model,
192
+ messages,
193
+ temperature,
194
+ topP,
195
+ topK,
196
+ onError : ( { error } ) => {
197
+ throw new Error ( 'failed to call the model' , { cause : error } ) ;
198
+ } ,
199
+ } ) ,
197
200
} ) ;
198
201
199
202
// parse approved flag
@@ -202,6 +205,7 @@ async function generateApprovalCheckStatus(
202
205
// return
203
206
return {
204
207
...result ,
208
+ messages : [ ...messages , ...result . messages ] ,
205
209
approved,
206
210
} ;
207
211
}
0 commit comments