@@ -45,6 +45,33 @@ async function runLogParser(options) {
4545 return null ;
4646 }
4747
48+ /**
49+ * Count valid JSONL entries from a safe outputs file.
50+ * @param {string } content - Raw safe outputs JSONL content
51+ * @returns {number } Number of valid entries
52+ */
53+ function countSafeOutputEntries ( content ) {
54+ if ( ! content || content . trim ( ) . length === 0 ) {
55+ return 0 ;
56+ }
57+
58+ let count = 0 ;
59+ const lines = content . trim ( ) . split ( / \r ? \n / ) ;
60+ for ( const line of lines ) {
61+ const trimmedLine = line . trim ( ) ;
62+ if ( ! trimmedLine ) {
63+ continue ;
64+ }
65+ try {
66+ JSON . parse ( trimmedLine ) ;
67+ count ++ ;
68+ } catch ( e ) {
69+ // Ignore invalid JSONL lines
70+ }
71+ }
72+ return count ;
73+ }
74+
4875 try {
4976 const logPath = process . env . GH_AW_AGENT_OUTPUT ;
5077 if ( ! logPath ) {
@@ -120,18 +147,20 @@ async function runLogParser(options) {
120147 logEntries = result . logEntries || null ;
121148 }
122149
123- if ( markdown ) {
124- // Read safe outputs file if available
125- let safeOutputsContent = "" ;
126- const safeOutputsPath = process . env . GH_AW_SAFE_OUTPUTS ;
127- if ( safeOutputsPath && fs . existsSync ( safeOutputsPath ) ) {
128- try {
129- safeOutputsContent = fs . readFileSync ( safeOutputsPath , "utf8" ) ;
130- } catch ( error ) {
131- core . warning ( `Failed to read safe outputs file: ${ getErrorMessage ( error ) } ` ) ;
132- }
150+ // Read safe outputs file if available
151+ let safeOutputsContent = "" ;
152+ let safeOutputEntriesCount = 0 ;
153+ const safeOutputsPath = process . env . GH_AW_SAFE_OUTPUTS ;
154+ if ( safeOutputsPath && fs . existsSync ( safeOutputsPath ) ) {
155+ try {
156+ safeOutputsContent = fs . readFileSync ( safeOutputsPath , "utf8" ) ;
157+ safeOutputEntriesCount = countSafeOutputEntries ( safeOutputsContent ) ;
158+ } catch ( error ) {
159+ core . warning ( `Failed to read safe outputs file: ${ getErrorMessage ( error ) } ` ) ;
133160 }
161+ }
134162
163+ if ( markdown ) {
135164 // Generate lightweight plain text summary for core.info and Copilot CLI style for step summary
136165 if ( logEntries && Array . isArray ( logEntries ) && logEntries . length > 0 ) {
137166 // Extract model from init entry if available
@@ -215,7 +244,11 @@ async function runLogParser(options) {
215244 // Handle MCP server failures if present
216245 if ( mcpFailures && mcpFailures . length > 0 ) {
217246 const failedServers = mcpFailures . join ( ", " ) ;
218- core . setFailed ( `${ ERR_API } : MCP server(s) failed to launch: ${ failedServers } ` ) ;
247+ if ( safeOutputEntriesCount > 0 ) {
248+ core . warning ( `MCP server(s) failed to launch (${ failedServers } ), but agent completed with ${ safeOutputEntriesCount } safe output ${ safeOutputEntriesCount === 1 ? "entry" : "entries" } ` ) ;
249+ } else {
250+ core . setFailed ( `${ ERR_API } : MCP server(s) failed to launch: ${ failedServers } ` ) ;
251+ }
219252 }
220253
221254 // Handle max-turns limit if hit
0 commit comments