@@ -30,6 +30,42 @@ const correlations = (event: FlueObservation) => ({
3030 : { submissionId : event . submissionId } ) ,
3131} ) ;
3232
33+ // Failure text from the provider or runtime, never model output. Bounded so
34+ // a provider that echoes a large request cannot flood the log.
35+ const ERROR_TEXT_LIMIT = 2_000 ;
36+ const bounded = ( text : string | undefined ) =>
37+ text === undefined || text === ""
38+ ? undefined
39+ : text . slice ( 0 , ERROR_TEXT_LIMIT ) ;
40+
41+ const failure = ( error : {
42+ type ?: string ;
43+ name ?: string ;
44+ code ?: string ;
45+ message ?: string ;
46+ details ?: string ;
47+ } ) => {
48+ const fields = {
49+ errorType : error . type ,
50+ errorName : error . name ,
51+ errorCode : error . code ,
52+ errorMessage : bounded ( error . message ) ,
53+ errorDetails : bounded ( error . details ) ,
54+ } ;
55+ return Object . fromEntries (
56+ Object . entries ( fields ) . filter ( ( [ , value ] ) => value !== undefined ) ,
57+ ) ;
58+ } ;
59+
60+ const unknownFailure = ( error : unknown ) =>
61+ error instanceof Error
62+ ? failure ( { name : error . name , message : error . message } )
63+ : typeof error === "string"
64+ ? failure ( { message : error } )
65+ : error === undefined
66+ ? { }
67+ : failure ( { message : JSON . stringify ( error ) } ) ;
68+
3369const observeFlueEvent = (
3470 event : FlueObservation ,
3571 context : FlueEventContext ,
@@ -154,10 +190,30 @@ const observeFlueEvent = (
154190 } ) ;
155191 return persistence ;
156192 case "submission_settled" :
157- agentLifecycleLogger . info ( "Flue submission settled." , {
193+ if ( event . outcome === "failed" )
194+ agentLifecycleLogger . error ( "Flue submission failed." , {
195+ event : event . type ,
196+ ...correlations ( event ) ,
197+ outcome : event . outcome ,
198+ ...( event . error === undefined ? { } : failure ( event . error ) ) ,
199+ } ) ;
200+ else
201+ agentLifecycleLogger . info ( "Flue submission settled." , {
202+ event : event . type ,
203+ ...correlations ( event ) ,
204+ outcome : event . outcome ,
205+ } ) ;
206+ return persistence ;
207+ case "submission_recovery" :
208+ agentLifecycleLogger . warn ( "Flue submission recovery step failed." , {
158209 event : event . type ,
159210 ...correlations ( event ) ,
211+ kind : event . kind ,
212+ operation : event . operation ,
160213 outcome : event . outcome ,
214+ attemptCount : event . attemptCount ,
215+ maxAttempts : event . maxAttempts ,
216+ ...( event . error === undefined ? { } : failure ( event . error ) ) ,
161217 } ) ;
162218 return persistence ;
163219 case "turn_start" :
@@ -182,7 +238,7 @@ const observeFlueEvent = (
182238 return persistence ;
183239 case "turn" : {
184240 const usage = event . response . usage ;
185- agentModelLogger . info ( "Flue model turn completed." , {
241+ const fields = {
186242 event : event . type ,
187243 ...correlations ( event ) ,
188244 turnId : event . turnId ,
@@ -191,6 +247,17 @@ const observeFlueEvent = (
191247 requestedModel : event . request . requestedModel ,
192248 durationMs : event . durationMs ,
193249 isError : event . isError ,
250+ ...( event . isError
251+ ? {
252+ finishReason : event . response . finishReason ,
253+ providerFinishReason : event . response . providerFinishReason ,
254+ // Flue copies an in-band failure, such as Claude Code's, from
255+ // the assistant message into this error.
256+ ...( event . response . error === undefined
257+ ? { }
258+ : failure ( event . response . error ) ) ,
259+ }
260+ : { } ) ,
194261 ...( usage === undefined
195262 ? { }
196263 : {
@@ -200,7 +267,10 @@ const observeFlueEvent = (
200267 cacheWriteTokens : usage . cacheWrite ,
201268 totalTokens : usage . totalTokens ,
202269 } ) ,
203- } ) ;
270+ } ;
271+ if ( event . isError )
272+ agentModelLogger . error ( "Flue model turn failed." , fields ) ;
273+ else agentModelLogger . info ( "Flue model turn completed." , fields ) ;
204274 return persistence ;
205275 }
206276 case "compaction_start" :
@@ -211,16 +281,23 @@ const observeFlueEvent = (
211281 estimatedTokens : event . estimatedTokens ,
212282 } ) ;
213283 return persistence ;
214- case "compaction" :
215- agentModelLogger . info ( "Flue compaction completed." , {
284+ case "compaction" : {
285+ const fields = {
216286 event : event . type ,
217287 ...correlations ( event ) ,
218288 isError : event . isError ,
219289 messagesBefore : event . messagesBefore ,
220290 messagesAfter : event . messagesAfter ,
221291 durationMs : event . durationMs ,
222- } ) ;
292+ } ;
293+ if ( event . isError )
294+ agentModelLogger . error ( "Flue compaction failed." , {
295+ ...fields ,
296+ ...unknownFailure ( event . error ) ,
297+ } ) ;
298+ else agentModelLogger . info ( "Flue compaction completed." , fields ) ;
223299 return persistence ;
300+ }
224301 case "tool_start" :
225302 agentToolLogger . info ( "Flue tool execution started." , {
226303 event : event . type ,
0 commit comments