Rejection sampling is straightforward to implement for this case.
import numpy as np
def rng_xpy(n, rng=None, chunk_size=1024):
rng = np.random.default_rng(rng)
rvs = 
n_drawn = 0
while n_drawn < n:
# Draw numbers from U(0, 1) for x, y, and z
# We draw numbers in chunks for efficiency
x, y, z = rng.random((3, chunk_size))
# Scale z to the maximum value of x+y
z *= 2
# We only want to use (x, y) values when z is less than x+y
good_mask = z <= (x + y)
xy = np.column_stack([x, y])[good_mask]
n_drawn += len(xy)
# Because we draw in chunks, we probably drew too many.
# Assemble the final array and trim it to the required number.
xy = np.concatenate(rvs, axis=0)[:n]