@@ -246,17 +246,22 @@ func (r *runtime) RunStream(ctx context.Context, sess *session.Session) <-chan E
246246 streamSpan .End ()
247247 slog .Debug ("Stream processed" , "agent" , a .Name (), "tool_calls" , len (calls ), "content_length" , len (content ), "stopped" , stopped )
248248
249- // Add assistant message to conversation history
250- assistantMessage := chat.Message {
251- Role : chat .MessageRoleAssistant ,
252- Content : content ,
253- ReasoningContent : reasoningContent ,
254- ToolCalls : calls ,
255- CreatedAt : time .Now ().Format (time .RFC3339 ),
256- }
249+ // Add assistant message to conversation history, but skip empty assistant messages
250+ // Providers reject assistant messages that have neither content nor tool calls.
251+ if strings .TrimSpace (content ) != "" || len (calls ) > 0 {
252+ assistantMessage := chat.Message {
253+ Role : chat .MessageRoleAssistant ,
254+ Content : content ,
255+ ReasoningContent : reasoningContent ,
256+ ToolCalls : calls ,
257+ CreatedAt : time .Now ().Format (time .RFC3339 ),
258+ }
257259
258- sess .AddMessage (session .NewAgentMessage (a , & assistantMessage ))
259- slog .Debug ("Added assistant message to session" , "agent" , a .Name (), "total_messages" , len (sess .GetAllMessages ()))
260+ sess .AddMessage (session .NewAgentMessage (a , & assistantMessage ))
261+ slog .Debug ("Added assistant message to session" , "agent" , a .Name (), "total_messages" , len (sess .GetAllMessages ()))
262+ } else {
263+ slog .Debug ("Skipping empty assistant message (no content and no tool calls)" , "agent" , a .Name ())
264+ }
260265
261266 contextLimit := 0
262267 if m != nil {
@@ -371,7 +376,7 @@ func (r *runtime) handleStream(ctx context.Context, stream chat.MessageStream, a
371376 continue
372377 }
373378 choice := response .Choices [0 ]
374- if choice .FinishReason == chat .FinishReasonStop {
379+ if choice .FinishReason == chat .FinishReasonStop || choice . FinishReason == chat . FinishReasonLength {
375380 return toolCalls , fullContent .String (), fullReasoningContent .String (), true , nil
376381 }
377382
@@ -438,7 +443,10 @@ func (r *runtime) handleStream(ctx context.Context, stream chat.MessageStream, a
438443 }
439444 }
440445
441- return toolCalls , fullContent .String (), fullReasoningContent .String (), false , nil
446+ // If the stream completed without producing any content or tool calls, likely because of a token limit, stop to avoid breaking the request loop
447+ // NOTE(krissetto): this can likely be removed once compaction works properly with all providers (aka dmr)
448+ stoppedDueToNoOutput := fullContent .Len () == 0 && len (toolCalls ) == 0
449+ return toolCalls , fullContent .String (), fullReasoningContent .String (), stoppedDueToNoOutput , nil
442450}
443451
444452// processToolCalls handles the execution of tool calls for an agent
0 commit comments