arazzo: 1.0.1 info: title: Adobe Photoshop Generative Fill from a Generated Mask summary: Generate a subject mask with background removal, then fill the masked area with generative AI. description: >- Generative fill needs a mask, and the background removal endpoint can produce one. This workflow runs removal in mask mode to derive a grayscale mask of the subject, waits for it, and then hands the source image plus that mask to the generative fill endpoint, which synthesizes new content into the masked region. This removes the usual prerequisite of authoring a mask by hand before calling the generative endpoint. Every step spells out its request inline so the flow can be read and executed without opening the underlying OpenAPI. version: 1.0.0 sourceDescriptions: - name: photoshopApi url: ../openapi/adobe-photoshop-api-openapi-original.yml type: openapi workflows: - workflowId: generative-fill summary: Derive a mask via background removal and fill that region with generative AI. description: >- Submits the image for mask-mode background removal, polls the Sensei job for the mask, then submits the image and mask to the generative fill endpoint and polls that job to completion. inputs: type: object required: - imageUrl properties: imageUrl: type: string description: Pre-signed GET URL of the source image to fill. steps: - stepId: submitMask description: >- Run background removal in mask mode, which returns a grayscale mask of the detected subject rather than a cutout. That mask defines the region the generative fill step will replace. operationId: removeBackgroundV2 requestBody: contentType: application/json payload: image: source: url: $inputs.imageUrl mode: mask output: mediaType: image/png successCriteria: - condition: $statusCode == 202 outputs: statusHref: $response.body#/_links/self/href - stepId: awaitMask description: >- Poll the Sensei status endpoint until the mask is ready. The submit call returns the absolute status URL in _links.self.href; the jobId this operation requires is the final path segment of that URL, so a runner takes that segment from statusHref before issuing the request. operationId: getSenseiJobStatus parameters: - name: jobId in: path value: $steps.submitMask.outputs.statusHref successCriteria: - condition: $statusCode == 200 - context: $response.body condition: $.outputs[0].status == 'succeeded' type: jsonpath onFailure: - name: keepPolling type: retry retryAfter: 3 retryLimit: 20 criteria: - context: $response.body condition: $.outputs[0].status == 'pending' || $.outputs[0].status == 'running' type: jsonpath - name: maskFailed type: end criteria: - context: $response.body condition: $.outputs[0].status == 'failed' type: jsonpath outputs: maskHref: $response.body#/outputs/0/_links/self/href - stepId: submitFill description: >- Submit the original image together with the generated mask so the generative service synthesizes new content into the masked region. operationId: fillMaskedAreas requestBody: contentType: application/json payload: image: source: url: $inputs.imageUrl masks: - source: url: $steps.awaitMask.outputs.maskHref successCriteria: - condition: $statusCode == 202 outputs: statusHref: $response.body#/_links/self/href - stepId: awaitFill description: >- Poll the Sensei status endpoint until the generative fill job reports succeeded and the filled image is available. operationId: getSenseiJobStatus parameters: - name: jobId in: path value: $steps.submitFill.outputs.statusHref successCriteria: - condition: $statusCode == 200 - context: $response.body condition: $.outputs[0].status == 'succeeded' type: jsonpath onFailure: - name: keepPolling type: retry retryAfter: 3 retryLimit: 20 criteria: - context: $response.body condition: $.outputs[0].status == 'pending' || $.outputs[0].status == 'running' type: jsonpath - name: fillFailed type: end criteria: - context: $response.body condition: $.outputs[0].status == 'failed' type: jsonpath outputs: status: $response.body#/outputs/0/status filledHref: $response.body#/outputs/0/_links/self/href outputs: maskHref: $steps.awaitMask.outputs.maskHref filledHref: $steps.awaitFill.outputs.filledHref status: $steps.awaitFill.outputs.status