Repository: All-Hands-AI/OpenHands
File: openhands/memory/conversation_memory.py (Python)

Code before:
            return

        # We expect events[0] to be SystemMessageAction after _ensure_system_message
        if len(events) == 1:
            # Only system message exists
            logger.info(
                'Initial user message action was missing. Inserting the initial user message.'
            )
            events.insert(1, initial_user_action)
        elif not isinstance(events[1], MessageAction) or events[1].source != 'user':
            # The second event exists but is not the correct initial user message action.
            # We will insert the correct one provided.
            logger.info(
                'Second event was not the initial user message action. Inserting correct one at index 1.'
            )

            # Insert the user message event at index 1. This will be the second message as LLM APIs expect
            # but something was wrong with the history, so log all we can.
            events.insert(1, initial_user_action)

        # Else: events[1] is already a user MessageAction.
        # Check if it matches the one provided (if any discrepancy, log warning but proceed).
        elif events[1] != initial_user_action:
            logger.debug(
                'The user MessageAction at index 1 does not match the provided initial_user_action. '
                'Proceeding with the one found in condensed history.'
            )


Review comment (suggestion):
Note for v1: since the `ConversationMemory` class no longer exists, there is no mechanism for inserting the initial user message. It exists in the event stream like any other message would. No updates necessary.

Code after:
        self,
        events: list[Event],
        initial_user_action: MessageAction,
        forgotten_event_ids: set[int],
    ) -> None:
        """Checks if the second event is a user MessageAction and inserts the provided one if needed.

        IMPORTANT: If the initial user action has been condensed (its ID is in forgotten_event_ids),
        we do NOT re-insert it. This prevents old instructions from being re-executed after
        conversation condensation. The condensation summary already contains the context of
        what was requested and completed.

        Args:
            events: The list of events to modify in-place
            initial_user_action: The initial user message action from the full history
            forgotten_event_ids: Set of event IDs that have been forgotten/condensed
        """
        if (
            not events
        ):  # Should have system message from previous step, but safety check
            logger.error('Cannot ensure initial user message: event list is empty.')
            # Or raise? Let's log for now, _ensure_system_message should handle this.
            return

        # Check if the initial user action has been condensed/forgotten.
        # If so, we should NOT re-insert it to prevent re-execution of old instructions.
        # The condensation summary already contains the context of what was requested.
        initial_user_action_id = initial_user_action.id
        if initial_user_action_id in forgotten_event_ids:
            logger.info(
                f'Initial user action (id={initial_user_action_id}) has been condensed. '
                'Not re-inserting to prevent re-execution of old instructions.'
            )
            return

        # We expect events[0] to be SystemMessageAction after _ensure_system_message
        if len(events) == 1:
            # Only system message exists
            logger.info(
                'Initial user message action was missing. Inserting the initial user message.'
            )
            events.insert(1, initial_user_action)
        elif not isinstance(events[1], MessageAction) or events[1].source != 'user':
            # The second event exists but is not the correct initial user message action.
            # We will insert the correct one provided.
            logger.info(
                'Second event was not the initial user message action. Inserting correct one at index 1.'
            )

            # Insert the user message event at index 1. This will be the second message as LLM APIs expect
            # but something was wrong with the history, so log all we can.