@@ -9,6 +9,8 @@ const MAX_UPLOAD_FILE_BYTES = 4 * 1024 * 1024
99const MAX_TRANSCRIPT_EXECUTIONS = 64
1010const MAX_REVIEW_TEXT_BYTES = 32 * 1024
1111const MAX_TOOL_ARGUMENT_KEYS = 32
12+ const MAX_REVIEW_COLLECTION_ENTRIES = 64
13+ const MAX_REVIEW_VALUE_DEPTH = 8
1214const workspace = resolve ( process . env . AGENT_TASK_WORKSPACE || process . cwd ( ) )
1315const uploadPath = resolve ( process . env . AGENT_TASK_UPLOAD_PATH || join ( workspace , ".codebox" , "agent-task-upload" ) )
1416const requestPath = resolve ( process . env . AGENT_TASK_REQUEST_PATH || join ( workspace , ".codebox" , "agent-task-request.json" ) )
@@ -136,7 +138,10 @@ async function stageTextFile(source, destination, options = {}) {
136138 const contents = openedMetadata . isFile ( ) && openedMetadata . size <= MAX_UPLOAD_FILE_BYTES ? await handle . readFile ( ) : null
137139 await handle . close ( )
138140 if ( ! contents || contents . includes ( 0 ) || ! isUtf8 ( contents ) ) return false
139- const sanitized = options . compactNativeInput ? compactNativeInput ( contents . toString ( "utf8" ) ) : sanitizeText ( contents . toString ( "utf8" ) )
141+ const sourceText = contents . toString ( "utf8" )
142+ const sanitized = options . projectWorkflowResult
143+ ? `${ JSON . stringify ( projectWorkflowResult ( parseJsonOrEmpty ( sourceText ) ) , null , 2 ) } \n`
144+ : options . compactNativeInput ? compactNativeInput ( sourceText ) : sanitizeText ( sourceText )
140145 const text = redact ( sanitizeSeedSnapshotJson ( sanitized ) )
141146 assertNoRuntimeSourcePaths ( text , privateUploadRoots , "Runtime source or workspace paths must never be persisted in artifact uploads." )
142147 assertNoSeedSnapshotPaths ( text )
@@ -173,6 +178,51 @@ function boundedText(value) {
173178 return containsRuntimeSourceContent ( text ) ? "[redacted-source-content]" : text
174179}
175180
181+ function projectReviewValue ( value , depth = 0 ) {
182+ if ( depth >= MAX_REVIEW_VALUE_DEPTH ) return undefined
183+ if ( typeof value === "string" ) return boundedText ( value )
184+ if ( typeof value === "number" || typeof value === "boolean" || value === null ) return value
185+ if ( Array . isArray ( value ) ) return value . slice ( 0 , MAX_REVIEW_COLLECTION_ENTRIES ) . flatMap ( ( entry ) => {
186+ const projected = projectReviewValue ( entry , depth + 1 )
187+ return projected === undefined ? [ ] : [ projected ]
188+ } )
189+ return Object . fromEntries ( Object . entries ( record ( value ) ) . slice ( 0 , MAX_REVIEW_COLLECTION_ENTRIES ) . flatMap ( ( [ key , entry ] ) => {
190+ const projectedKey = boundedText ( key )
191+ const projected = projectReviewValue ( entry , depth + 1 )
192+ return projectedKey === undefined || projected === undefined ? [ ] : [ [ projectedKey , projected ] ]
193+ } ) )
194+ }
195+
196+ function projectWorkflowResult ( value ) {
197+ const result = record ( value )
198+ const execution = record ( result . execution )
199+ const outputs = record ( result . outputs )
200+ const reviewerEvidence = record ( result . reviewer_evidence )
201+ const verification = Array . isArray ( result . verification ) ? result . verification . slice ( 0 , MAX_REVIEW_COLLECTION_ENTRIES ) . map ( ( value ) => {
202+ const check = record ( value )
203+ return projectReviewValue ( Object . fromEntries ( [ "kind" , "command" , "description" , "success" , "exit_code" , "stdout_truncated" , "stderr_truncated" ] . flatMap ( ( key ) => check [ key ] === undefined ? [ ] : [ [ key , check [ key ] ] ] ) ) )
204+ } ) : undefined
205+ return projectReviewValue ( Object . fromEntries ( Object . entries ( {
206+ schema : result . schema ,
207+ run_id : result . run_id ,
208+ status : result . status ,
209+ success : result . success ,
210+ request_path : result . request_path ,
211+ execution : Object . keys ( execution ) . length ? { stdout_truncated : execution . stdout_truncated , stderr_truncated : execution . stderr_truncated } : undefined ,
212+ reviewer_evidence : reviewerEvidence . transcript === undefined ? undefined : { transcript : reviewerEvidence . transcript } ,
213+ verification,
214+ publication : result . publication ,
215+ transcript : result . transcript ,
216+ artifacts : result . artifacts ,
217+ outputs : outputs . projections === undefined ? undefined : { projections : outputs . projections } ,
218+ access : result . access ,
219+ publication_verification : result . publication_verification ,
220+ publication_error : result . publication_error ,
221+ failure : result . failure ,
222+ projection_error : result . projection_error ,
223+ } ) . filter ( ( [ , entry ] ) => entry !== undefined ) ) )
224+ }
225+
176226function safeTargetPath ( value ) {
177227 const path = safeRelativeArtifactPath ( value )
178228 return path ? `workspace/${ path } ` : undefined
@@ -417,7 +467,7 @@ const declaredPaths = new Set(declaredArtifactPaths(result, declarations(request
417467await rm ( uploadPath , { recursive : true , force : true } )
418468await mkdir ( uploadPath , { recursive : true } )
419469await stageTextFile ( requestPath , join ( uploadPath , ".codebox" , "agent-task-request.json" ) )
420- await stageTextFile ( resultSource , join ( uploadPath , ".codebox" , "agent-task-workflow-result.json" ) )
470+ await stageTextFile ( resultSource , join ( uploadPath , ".codebox" , "agent-task-workflow-result.json" ) , { projectWorkflowResult : true } )
421471await stageTextFile ( join ( workspace , ".codebox" , "native-agent-task-input.json" ) , join ( uploadPath , ".codebox" , "native-agent-task-input.json" ) , { compactNativeInput : true } )
422472for ( const path of declaredPaths ) {
423473 const source = resolve ( artifactsPath , path )
0 commit comments