def test_get_contextual_events_target_at_beginning():
    """
    Tests behavior when the target event_id is at the beginning of the stream,
    resulting in fewer than context_size events before it.
    """
    mock_event_stream = MagicMock(spec=EventStream)
    target_event_id = 1  # Target is the second event (IDs are 0-indexed in list, 1-indexed for events)
    context_size = 4

    all_event_specs = [
        {'id': 0, 'type': MessageAction, 'content': 'message_0_first'},
        {'id': 1, 'type': CmdRunAction, 'command': 'command_1_TARGET'},  # Target
        {'id': 2, 'type': CmdOutputObservation, 'content': 'obs_2', 'command_id': 1},
        {'id': 3, 'type': MessageAction, 'content': 'message_3'},
        {'id': 4, 'type': CmdRunAction, 'command': 'command_4'},
        {'id': 5, 'type': CmdOutputObservation, 'content': 'obs_5', 'command_id': 4},
        {
            'id': 6,
            'type': MessageAction,
            'content': 'message_6',
        },  # Should be fetched by 'after'
    ]
    all_events_objects = create_test_events(all_event_specs)
    events_by_id = {e.id: e for e in all_events_objects}

    # Before: start_id=1, reverse=True, limit=4. Candidates: [1,0]. Filtered: [1,0]. Result: [1,0]
    simulated_search_before = [events_by_id[1], events_by_id[0]]

    # After: start_id=2, limit=5. Candidates: [2,3,4,5,6]. Filtered: [2,3,4,5,6]. Result: [2,3,4,5,6]
    simulated_search_after = [
        events_by_id[2],
        events_by_id[3],
        events_by_id[4],
        events_by_id[5],
        events_by_id[6],
    ]

    mock_event_stream.search_events.side_effect = [
        simulated_search_before,
        simulated_search_after,
    ]

    result_str = _get_contextual_events(mock_event_stream, target_event_id)

    # Expected final: [event_obj_0, event_obj_1] (from before, reversed)
    # + [event_obj_2, event_obj_3, event_obj_4, event_obj_5, event_obj_6] (from after)
    expected_final_event_objects = [
        events_by_id[0],
        events_by_id[1],
        events_by_id[2],
        events_by_id[3],
        events_by_id[4],
        events_by_id[5],
        events_by_id[6],
    ]
    expected_output_str = '\n'.join(str(e) for e in expected_final_event_objects)

    assert result_str == expected_output_str

    calls = mock_event_stream.search_events.call_args_list
    assert len(calls) == 2
    # Call 1: Before events
    kwargs_before = calls[0][1]
    assert kwargs_before['start_id'] == target_event_id
    assert kwargs_before['limit'] == context_size
    # Call 2: After events
    kwargs_after = calls[1][1]
    assert kwargs_after['start_id'] == target_event_id + 1
    assert kwargs_after['limit'] == context_size + 1

    Tests behavior when the target event_id is at the beginning of the stream,
    resulting in fewer than context_size events before it.
    
tests/unit/test_contextual_events.py