@@ -422,39 +422,23 @@ func (wp *WorkerPool) processJob(workerID string, job *storage.ReviewJob) {
422422 // Dirty job - use pre-captured diff
423423 reviewPrompt , err = pb .BuildDirty (effectiveRepoPath , * job .DiffContent , job .RepoID , cfg .ReviewContextCount , job .Agent , job .ReviewType )
424424 } else {
425- // Normal job - build prompt from git ref.
426- reviewPrompt , err = pb .Build (
427- effectiveRepoPath , job .GitRef , job .RepoID ,
428- cfg .ReviewContextCount , job .Agent , job .ReviewType ,
425+ // Normal job - build prompt from git ref. Write the full
426+ // diff to a snapshot file so the builder can reference it
427+ // when the diff is too large to inline.
428+ excludes := config .ResolveExcludePatterns (
429+ effectiveRepoPath , cfg , job .ReviewType ,
429430 )
430- // If the diff was truncated for a Codex review, write a
431- // snapshot file so the sandboxed agent can read it directly
432- // instead of needing git commands.
433- if err == nil && strings .EqualFold (job .Agent , "codex" ) &&
434- strings .Contains (reviewPrompt , prompt .DiffTruncatedHint ) {
435- excludes := config .ResolveExcludePatterns (
436- effectiveRepoPath , cfg , job .ReviewType ,
437- )
438- diffFile , cleanup , diffFileErr := prepareDiffFileForCodex (
439- effectiveRepoPath , job , excludes ,
440- )
441- if cleanup != nil {
442- defer cleanup ()
443- }
444- if diffFile != "" {
445- reviewPrompt , err = pb .BuildWithDiffFile (
446- effectiveRepoPath , job .GitRef , job .RepoID ,
447- cfg .ReviewContextCount , job .Agent ,
448- job .ReviewType , diffFile ,
449- )
450- } else if diffFileErr != nil &&
451- requiresSandboxedCodexDiffFile (job , cfg ) {
452- err = fmt .Errorf ("prepare codex diff file: %w" , diffFileErr )
453- } else if diffFileErr != nil {
454- log .Printf ("[%s] Warning: codex diff file: %v" ,
455- workerID , diffFileErr )
456- }
431+ diffFile , cleanup := prepareDiffFile (
432+ effectiveRepoPath , job , excludes ,
433+ )
434+ if cleanup != nil {
435+ defer cleanup ()
457436 }
437+ reviewPrompt , err = pb .BuildWithDiffFile (
438+ effectiveRepoPath , job .GitRef , job .RepoID ,
439+ cfg .ReviewContextCount , job .Agent ,
440+ job .ReviewType , diffFile ,
441+ )
458442 }
459443 if err != nil {
460444 log .Printf ("[%s] Error building prompt: %v" , workerID , err )
@@ -1044,60 +1028,21 @@ func (wp *WorkerPool) failoverOrFail(
10441028func preparePrebuiltCodexPrompt (
10451029 repoPath string , job * storage.ReviewJob , reviewPrompt string , excludes []string ,
10461030) (string , func (), error ) {
1047- hasPlaceholder := strings .Contains (
1048- reviewPrompt , prompt .CodexDiffFilePathPlaceholder ,
1049- )
1050- // Legacy prebuilt prompts (created before diff-file support) won't
1051- // have the placeholder. For those, only write a diff file when the
1052- // prompt indicates the diff was truncated.
1053- if ! hasPlaceholder {
1054- if ! strings .EqualFold (job .Agent , "codex" ) ||
1055- ! strings .Contains (reviewPrompt , prompt .DiffTruncatedHint ) {
1056- return reviewPrompt , nil , nil
1057- }
1058- diffFile , cleanup , err := prepareDiffFileForCodex (
1059- repoPath , job , excludes ,
1060- )
1061- if err != nil || diffFile == "" {
1062- if cleanup != nil {
1063- cleanup ()
1064- }
1065- // Best-effort for legacy prompts: return as-is so the
1066- // old git-command fallback can still be attempted.
1067- return reviewPrompt , nil , nil
1068- }
1069- reviewPrompt += fmt .Sprintf (
1070- "\n \n The full diff is also available at: `cat %s`\n " ,
1071- shellQuoteForPrompt (diffFile ),
1072- )
1073- return reviewPrompt , cleanup , nil
1074- }
1075-
1076- diffFile , cleanup , err := prepareDiffFileForCodex (repoPath , job , excludes )
1077- if err != nil {
1078- if cleanup != nil {
1079- cleanup ()
1080- }
1081- return "" , nil , fmt .Errorf ("prepare prebuilt codex prompt diff file: %w" , err )
1031+ if ! strings .Contains (reviewPrompt , prompt .CodexDiffFilePathPlaceholder ) {
1032+ return reviewPrompt , nil , nil
10821033 }
1034+ diffFile , cleanup := prepareDiffFile (repoPath , job , excludes )
10831035 if diffFile == "" {
1084- if cleanup != nil {
1085- cleanup ()
1086- }
10871036 return "" , nil , fmt .Errorf (
1088- "prebuilt codex prompt needs diff file but none could be prepared" ,
1037+ "prebuilt prompt needs diff file but none could be prepared" ,
10891038 )
10901039 }
1091- quotedPlaceholder := shellQuoteForPrompt (
1092- prompt .CodexDiffFilePathPlaceholder ,
1093- )
1094- reviewPrompt = strings .ReplaceAll (
1095- reviewPrompt , quotedPlaceholder , shellQuoteForPrompt (diffFile ),
1040+ replacer := strings .NewReplacer (
1041+ shellQuoteForPrompt (prompt .CodexDiffFilePathPlaceholder ),
1042+ shellQuoteForPrompt (diffFile ),
1043+ prompt .CodexDiffFilePathPlaceholder , diffFile ,
10961044 )
1097- reviewPrompt = strings .ReplaceAll (
1098- reviewPrompt , prompt .CodexDiffFilePathPlaceholder , diffFile ,
1099- )
1100- return reviewPrompt , cleanup , nil
1045+ return replacer .Replace (reviewPrompt ), cleanup , nil
11011046}
11021047
11031048func shellQuoteForPrompt (s string ) string {
@@ -1107,24 +1052,6 @@ func shellQuoteForPrompt(s string) string {
11071052 return "'" + strings .ReplaceAll (s , "'" , `'\''` ) + "'"
11081053}
11091054
1110- func requiresSandboxedCodexDiffFile (
1111- job * storage.ReviewJob , cfg * config.Config ,
1112- ) bool {
1113- if ! strings .EqualFold (job .Agent , "codex" ) ||
1114- job .Agentic || agent .AllowUnsafeAgents () {
1115- return false
1116- }
1117- // Use the same config-aware resolution as the worker to check
1118- // whether Codex is the effective agent. If it falls back to
1119- // another agent (e.g., Codex is unavailable or overridden via
1120- // codex_cmd), the diff file is not required.
1121- a , err := agent .GetAvailableWithConfig (job .Agent , cfg )
1122- if err != nil {
1123- return false
1124- }
1125- return strings .EqualFold (a .Name (), "codex" )
1126- }
1127-
11281055// logJobFailed logs a job failure to the activity log
11291056func (wp * WorkerPool ) logJobFailed (
11301057 jobID int64 , workerID , agentName , errorMsg string ,
@@ -1144,21 +1071,13 @@ func (wp *WorkerPool) logJobFailed(
11441071 )
11451072}
11461073
1147- // prepareDiffFileForCodex writes the full diff for a job into the
1148- // checkout's git dir so a sandboxed Codex agent can read it without
1149- // needing git commands or access outside the repository boundary.
1150- // Returns the file path and a cleanup function, or ("", nil) when no
1151- // file was written.
1152- func prepareDiffFileForCodex (
1074+ // prepareDiffFile writes the full diff for a job into the checkout's
1075+ // git dir so the prompt builder can reference it when the diff is too
1076+ // large to inline. Returns the file path and a cleanup function, or
1077+ // ("", nil) on failure.
1078+ func prepareDiffFile (
11531079 repoPath string , job * storage.ReviewJob , excludes []string ,
1154- ) (string , func (), error ) {
1155- if ! strings .EqualFold (job .Agent , "codex" ) {
1156- return "" , nil , nil
1157- }
1158- // Job-specific agentic mode keeps the existing direct-tooling path.
1159- if job .Agentic {
1160- return "" , nil , nil
1161- }
1080+ ) (string , func ()) {
11621081 var fullDiff string
11631082 var err error
11641083 if gitpkg .IsRange (job .GitRef ) {
@@ -1170,27 +1089,26 @@ func prepareDiffFileForCodex(
11701089 repoPath , job .GitRef , excludes ... ,
11711090 )
11721091 }
1173- if err != nil {
1174- return "" , nil , fmt . Errorf ( "capture full diff: %w" , err )
1175- }
1176- if fullDiff == "" {
1177- return "" , nil , nil
1092+ if err != nil || fullDiff == "" {
1093+ if err != nil {
1094+ log . Printf ( "Warning: capture diff for snapshot: %v" , err )
1095+ }
1096+ return "" , nil
11781097 }
11791098 gitDir , err := gitpkg .ResolveGitDir (repoPath )
11801099 if err != nil {
1181- return "" , nil , fmt .Errorf ("resolve git dir: %w" , err )
1100+ log .Printf ("Warning: resolve git dir for diff snapshot: %v" , err )
1101+ return "" , nil
11821102 }
1183- if info , err := os .Stat (gitDir ); err != nil || ! info .IsDir () {
1184- if err != nil {
1185- return "" , nil , fmt .Errorf ("stat git dir: %w" , err )
1186- }
1187- return "" , nil , fmt .Errorf ("git dir %s is not a directory" , gitDir )
1188- }
1189- diffFile := filepath .Join (gitDir , fmt .Sprintf ("roborev-review-%d.diff" , job .ID ))
1103+ diffFile := filepath .Join (
1104+ gitDir ,
1105+ fmt .Sprintf ("roborev-review-%d.diff" , job .ID ),
1106+ )
11901107 if err := os .WriteFile (diffFile , []byte (fullDiff ), 0o644 ); err != nil {
1191- return "" , nil , fmt .Errorf ("write diff file %s: %w" , diffFile , err )
1108+ log .Printf ("Warning: write diff snapshot %s: %v" , diffFile , err )
1109+ return "" , nil
11921110 }
1193- return diffFile , func () { os .Remove (diffFile ) }, nil
1111+ return diffFile , func () { os .Remove (diffFile ) }
11941112}
11951113
11961114// markCompactSourceJobs marks all source jobs as closed for a completed compact job
0 commit comments