When you place two curves inside each other and fill the joined geometry, it automatically produces a boolean operation like you want:
But of course your problem is that this operation turns it into a mesh, so you can't use it as a profile curve to sweep along another curve anymore. To solve that, I simply "swept" the two cap curves (the square and the circle) separately. Sweeping the joined curve like you did creates the same result, shape-wise. However, flipping the faces inside the tube is more cumbersome that way, so if you care about all normals facing the correct direction, sweeping them separately might be desirable.
Now you can create the caps using the above method, then place them on the endpoints of the main curve with an Instance on Points node
Flip Faces, Realize Instances, and Merge by Distance nodes are just maintenance nodes to turn the whole thing into a single manifold mesh.