A general and uniform approach is to get the angle of both vectors
theta_u = math.atan2(ux, uy)
theta_v = math.atan2(vx, vy)
and to create a new vector with the average angle:
middle_theta = (theta_u+theta_v)/2
(bx, by) = (cos(middle_theta), sin(middle_theta))
This way, you avoid the pitfall that you observed with opposite vectors.
PS: Note that there is an ambiguity in what the "bisector" vector is: there are generally two bisector vectors (typically one for the smaller angle and one for the larger angle). If you want the bisector vector inside the smaller angle, then your original formula is quite good; you may handle separately the special case that you observed for instance by taking a vector orthogonal to any of the two input vectors (-uy/|u|, ux/|u|)
if your formula yields the null vector.