@@ -499,80 +499,17 @@ func (al *AgentLoop) runLLMIteration(ctx context.Context, messages []providers.M
499499 // Force compression
500500 al .forceCompression (opts .SessionKey )
501501
502- // Rebuild messages with compressed history
503- // Note: We need to reload history from session manager because forceCompression changed it
502+ // Rebuild messages with compressed history.
503+ // After forceCompression, session history already contains the current
504+ // user message (added in step 3 of runAgentLoop), so we pass an empty
505+ // currentMessage to BuildMessages to avoid duplicating it.
504506 newHistory := al .sessions .GetHistory (opts .SessionKey )
505507 newSummary := al .sessions .GetSummary (opts .SessionKey )
506508
507- // Re-create messages for the next attempt
508- // We keep the current user message (opts.UserMessage) effectively
509509 messages = al .contextBuilder .BuildMessages (
510510 newHistory ,
511511 newSummary ,
512- opts .UserMessage ,
513- nil ,
514- opts .Channel ,
515- opts .ChatID ,
516- )
517-
518- // Important: If we are in the middle of a tool loop (iteration > 1),
519- // rebuilding messages from session history might duplicate the flow or miss context
520- // if intermediate steps weren't saved correctly.
521- // However, al.sessions.AddFullMessage is called after every tool execution,
522- // so GetHistory should reflect the current state including partial tool execution.
523- // But we need to ensure we don't duplicate the user message which is appended in BuildMessages.
524- // BuildMessages(history...) takes the stored history and appends the *current* user message.
525- // If iteration > 1, the "current user message" was already added to history in step 3 of runAgentLoop.
526- // So if we pass opts.UserMessage again, we might duplicate it?
527- // Actually, step 3 is: al.sessions.AddMessage(opts.SessionKey, "user", opts.UserMessage)
528- // So GetHistory ALREADY contains the user message!
529-
530- // CORRECTION:
531- // BuildMessages combines: [System] + [History] + [CurrentMessage]
532- // But Step 3 added CurrentMessage to History.
533- // So if we use GetHistory now, it has the user message.
534- // If we pass opts.UserMessage to BuildMessages, it adds it AGAIN.
535-
536- // For retry in the middle of a loop, we should rely on what's in the session.
537- // BUT checking BuildMessages implementation:
538- // It appends history... then appends currentMessage.
539-
540- // Logic fix for retry:
541- // If iteration == 1, opts.UserMessage corresponds to the user input.
542- // If iteration > 1, we are processing tool results. The "messages" passed to Chat
543- // already accumulated tool outputs.
544- // Rebuilding from session history is safest because it persists state.
545- // Start fresh with rebuilt history.
546-
547- // Special case: standard BuildMessages appends "currentMessage".
548- // If we are strictly retrying the *LLM call*, we want the exact same state as before but compressed.
549- // However, the "messages" argument passed to runLLMIteration is constructed by the caller.
550- // If we rebuild from Session, we need to know if "currentMessage" should be appended or is already in history.
551-
552- // In runAgentLoop:
553- // 3. sessions.AddMessage(userMsg)
554- // 4. runLLMIteration(..., UserMessage)
555-
556- // So History contains the user message.
557- // BuildMessages typically appends the user message as a *new* pending message.
558- // Wait, standard BuildMessages usage in runAgentLoop:
559- // messages := BuildMessages(history (has old), UserMessage)
560- // THEN AddMessage(UserMessage).
561- // So "history" passed to BuildMessages does NOT contain the current UserMessage yet.
562-
563- // But here, inside the loop, we have already saved it.
564- // So GetHistory() includes the current user message.
565- // If we call BuildMessages(GetHistory(), UserMessage), we get duplicates.
566-
567- // Hack/Fix:
568- // If we are retrying, we rebuild from Session History ONLY.
569- // We pass empty string as "currentMessage" to BuildMessages
570- // because the "current message" is already saved in history (step 3).
571-
572- messages = al .contextBuilder .BuildMessages (
573- newHistory ,
574- newSummary ,
575- "" , // Empty because history already contains the relevant messages
512+ "" ,
576513 nil ,
577514 opts .Channel ,
578515 opts .ChatID ,
0 commit comments