@@ -8,15 +8,15 @@ const OPENAI_API_KEY = "OPENAI_API_KEY";
88const MAX_PATCH_COUNT = process . env . MAX_PATCH_LENGTH
99 ? + process . env . MAX_PATCH_LENGTH
1010 : Infinity ;
11- const MAX_FILE_COUNT = 20 ;
11+ const MAX_FILE_COUNT = 30 ;
1212
1313// ํ์ผ ๋ณธ๋ฌธ์ ๊ฐ์ ธ์ฌ ๋ ํ์ฉํ๋ ์ต๋ ํฌ๊ธฐ (๋ฐ์ดํธ ๋จ์)
1414// ๋๋ฌด ํฐ ํ์ผ์ ๊ทธ๋๋ก ๋๋, ์ดํ prompt ๊ตฌ์ฑ ๋จ๊ณ์์ ์๋ผ๋
๋๋ค.
1515const MAX_FILE_BYTES = process . env . MAX_FILE_BYTES
1616 ? + process . env . MAX_FILE_BYTES
1717 : 64 * 1024 ; // ๊ธฐ๋ณธ 64KB
1818
19- // ํ๋กฌํํธ์ ํฌํจํ ์ ์๋ ์ต๋ ๋ฌธ์ ์ (๊ฐ๋๋ ์ผ)
19+ // ํ๋กฌํํธ์ ํฌํจํ ์ ์๋ ์ต๋ ๋ฌธ์ ์ (๊ฐ๋๋ ์ผ)
2020// ์ด ๊ฐ์ ๋์ด๊ฐ๋ฉด ์ค๊ฐ ๋ถ๋ถ์ ์๋ผ๋ด๊ณ ์/๋ค ์ผ๋ถ๋ง ๋จ๊น๋๋ค.
2121const MAX_CONTEXT_CHARS = process . env . MAX_CONTEXT_CHARS
2222 ? + process . env . MAX_CONTEXT_CHARS
@@ -36,7 +36,7 @@ const GLOBAL_CONTEXT_MODE = process.env.GLOBAL_CONTEXT_MODE || "meta"; // meta |
3636const fetchFileContent = async (
3737 context : Context ,
3838 path : string ,
39- ref : string ,
39+ ref : string
4040) : Promise < string | null > => {
4141 try {
4242 const repo = context . repo ( ) ;
@@ -77,18 +77,28 @@ const buildReviewInput = (
7777 filename : string ,
7878 content : string | null ,
7979 patch : string ,
80- globalContext : string | null ,
80+ globalContext : string | null
8181) : string => {
8282 const parts : string [ ] = [ ] ;
8383
8484 // ํ์ผ๋ณ ๋ฆฌ๋ทฐ ์ง์นจ์ ์ต์๋จ์ ๋ช
์ํด ์ ์ญ ์ปจํ
์คํธ ํธํฅ์ ์ค์ (STRICT)
8585 parts . push ( "## ๋ฆฌ๋ทฐ ์ง์นจ (STRICT)" ) ;
8686 parts . push ( "๋ค์์ ๋ฐ๋์ ์ค์ํ์ธ์ โ ์ด๊ธฐ๋ฉด ์ฐ์ถ๋ฌผ์ ์คํจ๋ก ๊ฐ์ฃผ๋ฉ๋๋ค." ) ;
87- parts . push ( "- **์ค์ฝํ: ์ด ํ์ผ์ Diff๋ง** ๋ค๋ฃน๋๋ค. ๋ค๋ฅธ ํ์ผ/์ผ๋ฐ๋ก ์ธ๊ธ ๊ธ์ง." ) ;
88- parts . push ( "- **๊ทผ๊ฑฐ ํ์:** ๋ชจ๋ ์ง์ ์ Diff์ `+`(์ถ๊ฐ) ๋ผ์ธ์ ๊ทผ๊ฑฐํด, ํด๋น ์ฝ๋ ์ค๋ํซ์ ์ธ๋ผ์ธ ์ฝ๋๋ก ํฌํจํ์ธ์." ) ;
89- parts . push ( "- **์ ์ญ ์ปจํ
์คํธ๋ ์ฐธ๊ณ ์ฉ**์
๋๋ค. ์ค์ฝํ๋ฅผ ๋ฒ์ด๋ ๋ด์ฉ์ด ํ์ํ๋ฉด ๊ทธ ํญ๋ชฉ์ **์์ฑํ์ง ๋ง์ธ์**." ) ;
90- parts . push ( "- **์ฐ์ ์์:** ๋ฒ๊ทธ/๋ณด์/์ฑ๋ฅ/ํ
์คํธ ์ค์ฌ. ์ฌ์ํ ์คํ์ผ/๊ฐ์ธ ์ทจํฅ ๊ธ์ง." ) ;
91- parts . push ( "- **์ค์ฝํ ์๋ฐ ๋ฐฉ์ง:** ๋ค๋ฅธ ํ์ผ์ด๋ ์ผ๋ฐ ๋ฒ ์คํธ ํ๋ํฐ์ค๋ง์ ์ธ๊ธํ๋ ค ํ ๊ฒฝ์ฐ, ํด๋น ์ฝ๋ฉํธ๋ ์๋ตํฉ๋๋ค." ) ;
87+ parts . push (
88+ "- **์ค์ฝํ: ์ด ํ์ผ์ Diff๋ง** ๋ค๋ฃน๋๋ค. ๋ค๋ฅธ ํ์ผ/์ผ๋ฐ๋ก ์ธ๊ธ ๊ธ์ง."
89+ ) ;
90+ parts . push (
91+ "- **๊ทผ๊ฑฐ ํ์:** ๋ชจ๋ ์ง์ ์ Diff์ `+`(์ถ๊ฐ) ๋ผ์ธ์ ๊ทผ๊ฑฐํด, ํด๋น ์ฝ๋ ์ค๋ํซ์ ์ธ๋ผ์ธ ์ฝ๋๋ก ํฌํจํ์ธ์."
92+ ) ;
93+ parts . push (
94+ "- **์ ์ญ ์ปจํ
์คํธ๋ ์ฐธ๊ณ ์ฉ**์
๋๋ค. ์ค์ฝํ๋ฅผ ๋ฒ์ด๋ ๋ด์ฉ์ด ํ์ํ๋ฉด ๊ทธ ํญ๋ชฉ์ **์์ฑํ์ง ๋ง์ธ์**."
95+ ) ;
96+ parts . push (
97+ "- **์ฐ์ ์์:** ๋ฒ๊ทธ/๋ณด์/์ฑ๋ฅ/ํ
์คํธ ์ค์ฌ. ์ฌ์ํ ์คํ์ผ/๊ฐ์ธ ์ทจํฅ ๊ธ์ง."
98+ ) ;
99+ parts . push (
100+ "- **์ค์ฝํ ์๋ฐ ๋ฐฉ์ง:** ๋ค๋ฅธ ํ์ผ์ด๋ ์ผ๋ฐ ๋ฒ ์คํธ ํ๋ํฐ์ค๋ง์ ์ธ๊ธํ๋ ค ํ ๊ฒฝ์ฐ, ํด๋น ์ฝ๋ฉํธ๋ ์๋ตํฉ๋๋ค."
101+ ) ;
92102
93103 parts . push ( `\n# File: ${ filename } ` ) ;
94104
@@ -102,15 +112,19 @@ const buildReviewInput = (
102112 if ( content ) {
103113 parts . push ( "\n## ํ์ฌ ํ์ผ ๋ด์ฉ (truncated)" ) ;
104114 parts . push ( "```" ) ;
105- parts . push ( truncateForPrompt ( content , allocateBudget ( MAX_CONTEXT_CHARS , 0.5 ) ) ) ;
115+ parts . push (
116+ truncateForPrompt ( content , allocateBudget ( MAX_CONTEXT_CHARS , 0.5 ) )
117+ ) ;
106118 parts . push ( "```" ) ;
107119 }
108120
109121 // (์ ํ) PR ์ ์ญ ์ปจํ
์คํธ๋ ๋งจ ์๋์ ์์น์์ผ ์ํฅ ์ต์ํ
110122 if ( globalContext ) {
111123 parts . push ( "\n---\n" ) ;
112124 parts . push ( "# PR ์ ์ญ ์ปจํ
์คํธ (์ฐธ๊ณ ์ฉ)" ) ;
113- parts . push ( truncateForPrompt ( globalContext , allocateBudget ( MAX_CONTEXT_CHARS , 0.4 ) ) ) ;
125+ parts . push (
126+ truncateForPrompt ( globalContext , allocateBudget ( MAX_CONTEXT_CHARS , 0.4 ) )
127+ ) ;
114128 }
115129
116130 return parts . join ( "\n" ) ;
@@ -163,7 +177,7 @@ export const robot = (app: Probot) => {
163177 owner : repo . owner ,
164178 repo : repo . repo ,
165179 name : OPENAI_API_KEY ,
166- } ,
180+ }
167181 ) ) as any ;
168182
169183 if ( ! data ?. value ) {
@@ -230,7 +244,7 @@ export const robot = (app: Probot) => {
230244 "compareCommits, base:" ,
231245 context . payload . pull_request . base . sha ,
232246 "head:" ,
233- context . payload . pull_request . head . sha ,
247+ context . payload . pull_request . head . sha
234248 ) ;
235249 log . debug ( "compareCommits.commits:" , commits ) ;
236250 log . debug ( "compareCommits.files" , changedFiles ) ;
@@ -254,8 +268,8 @@ export const robot = (app: Probot) => {
254268 pull_number : pull_request . number ,
255269 } ) ;
256270
257- hasSummaryReview = reviews . data . some (
258- ( review ) => review . body ?. includes ( "<!-- chatgpt-summary:v1 -->" ) ,
271+ hasSummaryReview = reviews . data . some ( ( review ) =>
272+ review . body ?. includes ( "<!-- chatgpt-summary:v1 -->" )
259273 ) ;
260274
261275 if ( hasSummaryReview ) {
@@ -310,7 +324,7 @@ export const robot = (app: Probot) => {
310324 let inlineFallback : string [ ] = [ ] ;
311325
312326 if ( isFileCountWithinLimit ) {
313- const aggregatedPatch = changedFiles
327+ const aggregatedPatch = changedFiles
314328 . filter (
315329 ( file ) =>
316330 ( file . status === "modified" || file . status === "added" ) &&
@@ -335,26 +349,43 @@ export const robot = (app: Probot) => {
335349 let globalContext : string | null = null ;
336350 {
337351 const prTitle = pull_request . title || "(no title)" ;
338- const changedFileList = changedFiles . map ( f => `- ${ f . filename } (${ f . status } )` ) . join ( "\n" ) ;
339- const summary = overallReview ?. summary ? `\n\n## ๋ณ๊ฒฝ ์์ฝ\n${ overallReview . summary } ` : "" ;
352+ const changedFileList = changedFiles
353+ . map ( ( f ) => `- ${ f . filename } (${ f . status } )` )
354+ . join ( "\n" ) ;
355+ const summary = overallReview ?. summary
356+ ? `\n\n## ๋ณ๊ฒฝ ์์ฝ\n${ overallReview . summary } `
357+ : "" ;
340358
341359 // meta ๋ชจ๋: ๋ฉํ๋ฐ์ดํฐ๋ง ์ ๊ณต (์ ๋ชฉ/์ปค๋ฐ ๋ฉ์์ง/ํ์ผ ๋ชฉ๋ก)
342360 if ( GLOBAL_CONTEXT_MODE === "meta" ) {
343361 globalContext = [
344362 `## PR ์ ๋ชฉ\n${ prTitle } ` ,
345- `\n## ์ปค๋ฐ ๋ฉ์์ง(์ง๊ณ)\n${ truncateForPrompt ( aggregatedCommitMessages , allocateBudget ( MAX_GLOBAL_CONTEXT_CHARS , 0.4 ) ) } ` ,
363+ `\n## ์ปค๋ฐ ๋ฉ์์ง(์ง๊ณ)\n${ truncateForPrompt (
364+ aggregatedCommitMessages ,
365+ allocateBudget ( MAX_GLOBAL_CONTEXT_CHARS , 0.4 )
366+ ) } `,
346367 `\n## ๋ณ๊ฒฝ ํ์ผ ๋ชฉ๋ก\n${ changedFileList } ` ,
347368 summary ,
348369 ] . join ( "\n" ) ;
349370 } else {
350371 // full ๋ชจ๋: ์ ์ฒด diff ๋ฐ์ท๋ฅผ ์๋๋ง ํฌํจ (ํ์ ํธํ)
351- const diffDigest = aggregatedPatch ? truncateForPrompt ( aggregatedPatch , allocateBudget ( MAX_GLOBAL_CONTEXT_CHARS , 0.3 ) ) : "" ;
372+ const diffDigest = aggregatedPatch
373+ ? truncateForPrompt (
374+ aggregatedPatch ,
375+ allocateBudget ( MAX_GLOBAL_CONTEXT_CHARS , 0.3 )
376+ )
377+ : "" ;
352378 globalContext = [
353379 `## PR ์ ๋ชฉ\n${ prTitle } ` ,
354- `\n## ์ปค๋ฐ ๋ฉ์์ง(์ง๊ณ)\n${ truncateForPrompt ( aggregatedCommitMessages , allocateBudget ( MAX_GLOBAL_CONTEXT_CHARS , 0.3 ) ) } ` ,
380+ `\n## ์ปค๋ฐ ๋ฉ์์ง(์ง๊ณ)\n${ truncateForPrompt (
381+ aggregatedCommitMessages ,
382+ allocateBudget ( MAX_GLOBAL_CONTEXT_CHARS , 0.3 )
383+ ) } `,
355384 `\n## ๋ณ๊ฒฝ ํ์ผ ๋ชฉ๋ก\n${ changedFileList } ` ,
356385 summary ,
357- diffDigest ? `\n\n## ์ ์ฒด diff (์ผ๋ถ ๋ฐ์ท)\n\n\`\`\`diff\n${ diffDigest } \n\`\`\`` : "" ,
386+ diffDigest
387+ ? `\n\n## ์ ์ฒด diff (์ผ๋ถ ๋ฐ์ท)\n\n\`\`\`diff\n${ diffDigest } \n\`\`\``
388+ : "" ,
358389 ] . join ( "\n" ) ;
359390 }
360391 }
@@ -388,7 +419,9 @@ export const robot = (app: Probot) => {
388419 }
389420
390421 if ( ! patch || patch . length > MAX_PATCH_COUNT ) {
391- log . info ( `${ file . filename } skipped caused by its diff is too large` ) ;
422+ log . info (
423+ `${ file . filename } skipped caused by its diff is too large`
424+ ) ;
392425 continue ;
393426 }
394427
@@ -398,16 +431,24 @@ export const robot = (app: Probot) => {
398431 fullContent = await fetchFileContent (
399432 context ,
400433 file . filename ,
401- context . payload . pull_request . head . sha ,
434+ context . payload . pull_request . head . sha
402435 ) ;
403- if ( fullContent && Buffer . byteLength ( fullContent , "utf-8" ) > MAX_FILE_BYTES ) {
436+ if (
437+ fullContent &&
438+ Buffer . byteLength ( fullContent , "utf-8" ) > MAX_FILE_BYTES
439+ ) {
404440 // Keep but it will be truncated by buildReviewInput/truncateForPrompt
405441 }
406442 } catch ( e ) {
407443 log . debug ( `content fetch failed for ${ file . filename } ` , e ) ;
408444 }
409445
410- const reviewInput = buildReviewInput ( file . filename , fullContent , patch , globalContext ) ;
446+ const reviewInput = buildReviewInput (
447+ file . filename ,
448+ fullContent ,
449+ patch ,
450+ globalContext
451+ ) ;
411452
412453 try {
413454 const res = await chat ?. codeReview ( reviewInput ) ;
@@ -420,20 +461,28 @@ export const robot = (app: Probot) => {
420461
421462 if ( ! res . lgtm || ( res . lgtm && REVIEW_ON_LGTM ) ) {
422463 if ( ! commentablePaths . has ( file . filename ) ) {
423- log . info ( `PR ํ์ผ์ patch๊ฐ ์์ด ${ file . filename } ์ ๋ํ ์ฝ๋ฉํธ ์๋ต` ) ;
424- inlineFallback . push ( `\n### ${ file . filename } \n${ res . review_comment } ` ) ;
464+ log . info (
465+ `PR ํ์ผ์ patch๊ฐ ์์ด ${ file . filename } ์ ๋ํ ์ฝ๋ฉํธ ์๋ต`
466+ ) ;
467+ inlineFallback . push (
468+ `\n### ${ file . filename } \n${ res . review_comment } `
469+ ) ;
425470 continue ;
426471 }
427472 // Compute position against the PR-wide patch to avoid misalignment
428473 const prWidePatch = prFilePatchByPath . get ( file . filename ) || patch ;
429- if ( ! prWidePatch || ! prWidePatch . includes ( '@@' ) ) {
430- inlineFallback . push ( `\n### ${ file . filename } \n${ res . review_comment } ` ) ;
474+ if ( ! prWidePatch || ! prWidePatch . includes ( "@@" ) ) {
475+ inlineFallback . push (
476+ `\n### ${ file . filename } \n${ res . review_comment } `
477+ ) ;
431478 continue ;
432479 }
433480
434481 const position = firstChangedPosition ( prWidePatch ) ;
435482 if ( ! Number . isSafeInteger ( position ) || position <= 0 ) {
436- inlineFallback . push ( `\n### ${ file . filename } \n${ res . review_comment } ` ) ;
483+ inlineFallback . push (
484+ `\n### ${ file . filename } \n${ res . review_comment } `
485+ ) ;
437486 continue ;
438487 }
439488 ress . push ( {
@@ -448,7 +497,9 @@ export const robot = (app: Probot) => {
448497 log . error ( `๋ฆฌ๋ทฐ ์คํจ: ${ file . filename } (status=${ status } )` ) ;
449498 if ( data ) {
450499 try {
451- log . error ( `GitHub API error payload: ${ JSON . stringify ( data , null , 2 ) } ` ) ;
500+ log . error (
501+ `GitHub API error payload: ${ JSON . stringify ( data , null , 2 ) } `
502+ ) ;
452503 } catch { }
453504 }
454505 log . error ( "์์ ์ค๋ฅ:" , e ) ;
@@ -482,7 +533,11 @@ export const robot = (app: Probot) => {
482533 const data = e ?. response ?. data ;
483534 log . error ( `๋ฆฌ๋ทฐ ์์ฑ ์คํจ (status=${ status } )` ) ;
484535 if ( data ) {
485- try { log . error ( `GitHub API error payload: ${ JSON . stringify ( data , null , 2 ) } ` ) ; } catch { }
536+ try {
537+ log . error (
538+ `GitHub API error payload: ${ JSON . stringify ( data , null , 2 ) } `
539+ ) ;
540+ } catch { }
486541 }
487542
488543 if ( status === 422 ) {
@@ -492,8 +547,13 @@ export const robot = (app: Probot) => {
492547 body = `<!-- chatgpt-summary:v1 -->\n${ overallReview . summary } ` ;
493548 }
494549
495- if ( typeof inlineFallback !== "undefined" && inlineFallback . length ) {
496- body += `\n\n---\nโ ๏ธ ์ธ๋ผ์ธ ์ฃผ์์ diff์ ๊ณ ์ ํ์ง ๋ชปํด ๋ณธ๋ฌธ์ ์ฒจ๋ถํฉ๋๋ค (422).` + inlineFallback . join ( "\n" ) ;
550+ if (
551+ typeof inlineFallback !== "undefined" &&
552+ inlineFallback . length
553+ ) {
554+ body +=
555+ `\n\n---\nโ ๏ธ ์ธ๋ผ์ธ ์ฃผ์์ diff์ ๊ณ ์ ํ์ง ๋ชปํด ๋ณธ๋ฌธ์ ์ฒจ๋ถํฉ๋๋ค (422).` +
556+ inlineFallback . join ( "\n" ) ;
497557 } else if ( ress . length ) {
498558 body += `\n\n(์ธ๋ผ์ธ ์ฝ๋ฉํธ๊ฐ ์์น ๋ถ์ผ์น๋ก ์๋ต๋์์ต๋๋ค.)` ;
499559 }
@@ -523,7 +583,7 @@ export const robot = (app: Probot) => {
523583 log . info ( "successfully reviewed" , context . payload . pull_request . html_url ) ;
524584
525585 return "success" ;
526- } ,
586+ }
527587 ) ;
528588} ;
529589
@@ -537,7 +597,7 @@ const matchPatterns = (patterns: string[], path: string) => {
537597 : pattern . startsWith ( "**" )
538598 ? pattern
539599 : "**/" + pattern ,
540- { dot : true , nocase : true } ,
600+ { dot : true , nocase : true }
541601 ) ;
542602 } catch {
543603 // if the pattern is not a valid glob pattern, try to match it as a regular expression
0 commit comments