Upload multiple files to the sandbox.
Implementations must support partial success - catch exceptions per-file
and return errors in FileUploadResponse objects rather than raising.
Upload files is responsible for ensuring that the parent path exists (if user permissions allow the user to write to the given directory)
upload_files(
self,
files: list[tuple[str, bytes]],
) -> list[FileUploadResponse]