From 29d5c529801bdb108c1f1ddc04731aa6840695af Mon Sep 17 00:00:00 2001 From: Jorge Cortes Date: Wed, 6 Nov 2024 18:18:25 -0500 Subject: [PATCH] [ACTION] Break Runware action into individual actions --- .../image-background-removal.mjs | 126 +++++ .../actions/image-caption/image-caption.mjs | 48 ++ .../image-control-net-preprocess.mjs | 126 +++++ .../image-inference/image-inference.mjs | 435 ++++++++++++++++++ .../actions/image-upscale/image-upscale.mjs | 73 +++ .../actions/prompt-enhance/prompt-enhance.mjs | 65 +++ .../actions/request-task/request-task.mjs | 176 ------- components/runware/common/constants.mjs | 28 ++ components/runware/package.json | 2 +- components/runware/runware.app.mjs | 73 +-- 10 files changed, 905 insertions(+), 247 deletions(-) create mode 100644 components/runware/actions/image-background-removal/image-background-removal.mjs create mode 100644 components/runware/actions/image-caption/image-caption.mjs create mode 100644 components/runware/actions/image-control-net-preprocess/image-control-net-preprocess.mjs create mode 100644 components/runware/actions/image-inference/image-inference.mjs create mode 100644 components/runware/actions/image-upscale/image-upscale.mjs create mode 100644 components/runware/actions/prompt-enhance/prompt-enhance.mjs delete mode 100644 components/runware/actions/request-task/request-task.mjs diff --git a/components/runware/actions/image-background-removal/image-background-removal.mjs b/components/runware/actions/image-background-removal/image-background-removal.mjs new file mode 100644 index 0000000000000..dcc124f11c4d0 --- /dev/null +++ b/components/runware/actions/image-background-removal/image-background-removal.mjs @@ -0,0 +1,126 @@ +import { v4 as uuid } from "uuid"; +import app from "../../runware.app.mjs"; +import constants from "../../common/constants.mjs"; + +export default { + key: "runware-image-background-removal", + name: "Image Background Removal", + description: "Request an image background removal task to be processed by the Runware API. [See the documentation](https://docs.runware.ai/en/image-editing/background-removal).", + version: "0.0.1", + type: "action", + props: { + app, + inputImage: { + propDefinition: [ + app, + "inputImage", + ], + }, + outputType: { + propDefinition: [ + app, + "outputType", + ], + }, + outputFormat: { + propDefinition: [ + app, + "outputFormat", + ], + }, + includeCost: { + propDefinition: [ + app, + "includeCost", + ], + }, + rgba: { + type: "string[]", + label: "RGBA", + description: "An array representing the `[red, green, blue, alpha]` values that define the color of the removed background. The alpha channel controls transparency. Eg. `[255, 255, 255, 0]`.", + optional: true, + }, + postProcessMask: { + type: "boolean", + label: "Post-Process Mask", + description: "Flag indicating whether to post-process the mask. Controls whether the mask should undergo additional post-processing. This step can improve the accuracy and quality of the background removal mask.", + optional: true, + }, + returnOnlyMask: { + type: "boolean", + label: "Return Only Mask", + description: "Flag indicating whether to return only the mask. The mask is the opposite of the image background removal.", + optional: true, + }, + alphaMatting: { + type: "boolean", + label: "Alpha Matting", + description: "Flag indicating whether to use alpha matting. Alpha matting is a post-processing technique that enhances the quality of the output by refining the edges of the foreground object.", + optional: true, + }, + alphaMattingForegroundThreshold: { + type: "integer", + label: "Alpha Matting Foreground Threshold", + description: "Threshold value used in alpha matting to distinguish the foreground from the background. Adjusting this parameter affects the sharpness and accuracy of the foreground object edges. Eg. `240`.", + optional: true, + min: 1, + max: 255, + }, + alphaMattingBackgroundThreshold: { + type: "integer", + label: "Alpha Matting Background Threshold", + description: "Threshold value used in alpha matting to refine the background areas. It influences how aggressively the algorithm removes the background while preserving image details. The higher the value, the more computation is needed and therefore the more expensive the operation is. Eg. `10`.", + optional: true, + min: 1, + max: 255, + }, + alphaMattingErodeSize: { + type: "integer", + label: "Alpha Matting Erode Size", + description: "Specifies the size of the erosion operation used in alpha matting. Erosion helps in smoothing the edges of the foreground object for a cleaner removal of the background. Eg. `10`.", + optional: true, + min: 1, + max: 255, + }, + }, + async run({ $ }) { + const { + app, + inputImage, + outputType, + outputFormat, + includeCost, + rgba, + postProcessMask, + returnOnlyMask, + alphaMatting, + alphaMattingForegroundThreshold, + alphaMattingBackgroundThreshold, + alphaMattingErodeSize, + } = this; + + const response = await app.post({ + $, + data: [ + { + taskType: constants.TASK_TYPE.IMAGE_BACKGROUND_REMOVAL.value, + taskUUID: uuid(), + inputImage, + outputType, + outputFormat, + includeCost, + rgba: rgba?.map(parseFloat), + postProcessMask, + returnOnlyMask, + alphaMatting, + alphaMattingForegroundThreshold, + alphaMattingBackgroundThreshold, + alphaMattingErodeSize, + }, + ], + }); + + $.export("$summary", `Successfully requested image background removal task with UUID \`${response.data[0].taskUUID}\`.`); + return response; + }, +}; diff --git a/components/runware/actions/image-caption/image-caption.mjs b/components/runware/actions/image-caption/image-caption.mjs new file mode 100644 index 0000000000000..dd3f12c1322d4 --- /dev/null +++ b/components/runware/actions/image-caption/image-caption.mjs @@ -0,0 +1,48 @@ +import { v4 as uuid } from "uuid"; +import app from "../../runware.app.mjs"; +import constants from "../../common/constants.mjs"; + +export default { + key: "runware-image-caption", + name: "Image Caption", + description: "Request an image caption task to be processed by the Runware API. [See the documentation](https://docs.runware.ai/en/utilities/image-to-text).", + version: "0.0.1", + type: "action", + props: { + app, + inputImage: { + propDefinition: [ + app, + "inputImage", + ], + }, + includeCost: { + propDefinition: [ + app, + "includeCost", + ], + }, + }, + async run({ $ }) { + const { + app, + inputImage, + includeCost, + } = this; + + const response = await app.post({ + $, + data: [ + { + taskType: constants.TASK_TYPE.IMAGE_CAPTION.value, + taskUUID: uuid(), + inputImage, + includeCost, + }, + ], + }); + + $.export("$summary", `Successfully requested image caption task with UUID \`${response.data[0].taskUUID}\`.`); + return response; + }, +}; diff --git a/components/runware/actions/image-control-net-preprocess/image-control-net-preprocess.mjs b/components/runware/actions/image-control-net-preprocess/image-control-net-preprocess.mjs new file mode 100644 index 0000000000000..fe5a1958b53be --- /dev/null +++ b/components/runware/actions/image-control-net-preprocess/image-control-net-preprocess.mjs @@ -0,0 +1,126 @@ +import { v4 as uuid } from "uuid"; +import app from "../../runware.app.mjs"; +import constants from "../../common/constants.mjs"; + +export default { + key: "runware-image-control-net-preprocess", + name: "Image Control Net Preprocess", + description: "Request an image control net preprocess task to be processed by the Runware API. [See the documentation](https://docs.runware.ai/en/image-editing/controlnet-tools).", + version: "0.0.1", + type: "action", + props: { + app, + inputImage: { + propDefinition: [ + app, + "inputImage", + ], + }, + outputType: { + propDefinition: [ + app, + "outputType", + ], + }, + outputFormat: { + propDefinition: [ + app, + "outputFormat", + ], + }, + includeCost: { + propDefinition: [ + app, + "includeCost", + ], + }, + preProcessorType: { + type: "string", + label: "Preprocessor Type", + description: "The preprocessor to be used.", + optional: true, + options: [ + "canny", + "depth", + "mlsd", + "normalbae", + "openpose", + "tile", + "seg", + "lineart", + "lineart_anime", + "shuffle", + "scribble", + "softedge", + ], + }, + height: { + propDefinition: [ + app, + "height", + ], + }, + width: { + propDefinition: [ + app, + "width", + ], + }, + lowThresholdCanny: { + type: "integer", + label: "Low Threshold Canny", + description: "Defines the lower threshold when using the Canny edge detection preprocessor. The recommended value is `100`.", + optional: true, + }, + highThresholdCanny: { + type: "integer", + label: "High Threshold Canny", + description: "Defines the high threshold when using the Canny edge detection preprocessor. The recommended value is `200`.", + optional: true, + }, + includeHandsAndFaceOpenPose: { + type: "boolean", + label: "Include Hands and Face OpenPose", + description: "Include the hands and face in the pose outline when using the OpenPose preprocessor.", + optional: true, + }, + }, + async run({ $ }) { + const { + app, + outputType, + outputFormat, + includeCost, + inputImage, + preProcessorType, + height, + width, + lowThresholdCanny, + highThresholdCanny, + includeHandsAndFaceOpenPose, + } = this; + + const response = await app.post({ + $, + data: [ + { + taskType: constants.TASK_TYPE.IMAGE_CONTROL_NET_PREPROCESS.value, + taskUUID: uuid(), + outputType, + outputFormat, + inputImage, + includeCost, + height, + width, + preProcessorType, + lowThresholdCanny, + highThresholdCanny, + includeHandsAndFaceOpenPose, + }, + ], + }); + + $.export("$summary", `Successfully requested image control net preprocess task with UUID \`${response.data[0].taskUUID}\`.`); + return response; + }, +}; diff --git a/components/runware/actions/image-inference/image-inference.mjs b/components/runware/actions/image-inference/image-inference.mjs new file mode 100644 index 0000000000000..f1daafceace2a --- /dev/null +++ b/components/runware/actions/image-inference/image-inference.mjs @@ -0,0 +1,435 @@ +import { v4 as uuid } from "uuid"; +import app from "../../runware.app.mjs"; +import constants from "../../common/constants.mjs"; + +export default { + key: "runware-image-inference", + name: "Image Inference", + description: "Request an image inference task to be processed by the Runware API. [See the documentation](https://docs.runware.ai/en/image-inference/api-reference).", + version: "0.0.1", + type: "action", + props: { + app, + structure: { + type: "string", + label: "Structure", + description: "The structure of the task to be processed.", + options: Object.values(constants.IMAGE_INFERENCE_STRUCTURE), + reloadProps: true, + }, + model: { + type: "string", + label: "Model", + description: "This identifier is a unique string that represents a specific model. You can find the AIR identifier of the model you want to use in our [Model Explorer](https://docs.runware.ai/en/image-inference/models#model-explorer), which is a tool that allows you to search for models based on their characteristics. More information about the AIR system can be found in the [Models page](https://docs.runware.ai/en/image-inference/models). Eg. `civitai:78605@83390`.", + }, + positivePrompt: { + type: "string", + label: "Positive Prompt", + description: "A positive prompt is a text instruction to guide the model on generating the image. It is usually a sentence or a paragraph that provides positive guidance for the task. This parameter is essential to shape the desired results. For example, if the positive prompt is `dragon drinking coffee`, the model will generate an image of a dragon drinking coffee. The more detailed the prompt, the more accurate the results. The length of the prompt must be between 4 and 2000 characters.", + }, + height: { + propDefinition: [ + app, + "height", + ], + }, + width: { + propDefinition: [ + app, + "width", + ], + }, + uploadEndpoint: { + type: "string", + label: "Upload Endpoint", + description: "This parameter allows you to specify a URL to which the generated image will be uploaded as binary image data using the HTTP PUT method. For example, an S3 bucket URL can be used as the upload endpoint. When the image is ready, it will be uploaded to the specified URL.", + optional: true, + }, + checkNSFW: { + type: "boolean", + label: "Check NSFW", + description: "This parameter is used to enable or disable the NSFW check. When enabled, the API will check if the image contains NSFW (not safe for work) content. This check is done using a pre-trained model that detects adult content in images. When the check is enabled, the API will return `NSFWContent: true` in the response object if the image is flagged as potentially sensitive content. If the image is not flagged, the API will return `NSFWContent: false`. If this parameter is not used, the parameter `NSFWContent` will not be included in the response object. Adds `0.1` seconds to image inference time and incurs additional costs. The NSFW filter occasionally returns false positives and very rarely false negatives.", + optional: true, + }, + includeCost: { + propDefinition: [ + app, + "includeCost", + ], + }, + scheduler: { + type: "string", + label: "Scheduler", + description: "An scheduler is a component that manages the inference process. Different schedulers can be used to achieve different results like more detailed images, faster inference, or more accurate results. The default scheduler is the one that the model was trained with, but you can choose a different one to get different results. Schedulers are explained in more detail in the [Schedulers page](https://docs.runware.ai/en/image-inference/schedulers).", + optional: true, + }, + seed: { + type: "string", + label: "Seed", + description: "A seed is a value used to randomize the image generation. If you want to make images reproducible (generate the same image multiple times), you can use the same seed value. When requesting multiple images with the same seed, the seed will be incremented by 1 (+1) for each image generated. Min: `0` Max: `9223372036854776000`. Defaults to `Random`.", + optional: true, + }, + numberResults: { + type: "integer", + label: "Number Of Results", + description: "The number of images to generate from the specified prompt. If **Seed** is set, it will be incremented by 1 (+1) for each image generated.", + optional: true, + }, + }, + additionalProps() { + const { structure } = this; + + const seedImage = { + type: "string", + label: "Seed Image", + description: "When doing Image-to-Image, Inpainting or Outpainting, this parameter is **required**. Specifies the seed image to be used for the diffusion process. The image can be specified in one of the following formats:\n - An UUID v4 string of a [previously uploaded image](https://docs.runware.ai/en/getting-started/image-upload) or a [generated image](https://docs.runware.ai/en/image-inference/api-reference).\n - A data URI string representing the image. The data URI must be in the format `data:;base64,` followed by the base64-encoded image. For example: `data:image/png;base64,iVBORw0KGgo...`.\n - A base64 encoded image without the data URI prefix. For example: `iVBORw0KGgo...`.\n - A URL pointing to the image. The image must be accessible publicly. Supported formats are: PNG, JPG and WEBP.", + }; + + const maskImage = { + type: "string", + label: "Mask Image", + description: "When doing Inpainting or Outpainting, this parameter is **required**. Specifies the mask image to be used for the inpainting process. The image can be specified in one of the following formats:\n - An UUID v4 string of a [previously uploaded image](https://docs.runware.ai/en/getting-started/image-upload) or a [generated image](https://docs.runware.ai/en/image-inference/api-reference).\n - A data URI string representing the image. The data URI must be in the format `data:;base64,` followed by the base64-encoded image. For example: `data:image/png;base64,iVBORw0KGgo...`.\n - A base64 encoded image without the data URI prefix. For example: `iVBORw0KGgo...`.\n - A URL pointing to the image. The image must be accessible publicly. Supported formats are: PNG, JPG and WEBP.", + }; + + const strength = { + type: "string", + label: "Strength", + description: "When doing Image-to-Image, Inpainting or Outpainting, this parameter is used to determine the influence of the **Seed Image** image in the generated output. A higher value results in more influence from the original image, while a lower value allows more creative deviation. Min: `0` Max: `1` and Default: `0.8`.", + optional: true, + }; + + const controlNetModel = { + type: "string", + label: "ControlNet Model 0", + description: "For basic/common ControlNet models, you can check the list of available models [here](https://docs.runware.ai/en/image-inference/models#basic-controlnet-models). For custom or specific ControlNet models, we make use of the [AIR system](https://github.com/civitai/civitai/wiki/AIR-%E2%80%90-Uniform-Resource-Names-for-AI) to identify ControlNet models. This identifier is a unique string that represents a specific model. You can find the AIR identifier of the ControlNet model you want to use in our [Model Explorer](https://docs.runware.ai/en/image-inference/models#model-explorer), which is a tool that allows you to search for models based on their characteristics. More information about the AIR system can be found in the [Models page](https://docs.runware.ai/en/image-inference/models).", + }; + + const controlNetGuideImage = { + type: "string", + label: "ControlNet Guide Image 0", + description: "The guide image for ControlNet.", + }; + + const controlNetWeight = { + type: "integer", + label: "ControlNet Weight 0", + description: "The weight for ControlNet.", + }; + + const controlNetStartStep = { + type: "integer", + label: "ControlNet Start Step 0", + description: "The start step for ControlNet.", + }; + + const controlNetEndStep = { + type: "integer", + label: "ControlNet End Step 0", + description: "The end step for ControlNet.", + }; + + const controlNetControlMode = { + type: "string", + label: "ControlNet Control Mode 0", + description: "The control mode for ControlNet.", + }; + + const loraModel = { + type: "string", + label: "LoRA Model 0", + description: "We make use of the [AIR system](https://github.com/civitai/civitai/wiki/AIR-%E2%80%90-Uniform-Resource-Names-for-AI) to identify LoRA models. This identifier is a unique string that represents a specific model. You can find the AIR identifier of the LoRA model you want to use in our [Model Explorer](https://docs.runware.ai/en/image-inference/models#model-explorer), which is a tool that allows you to search for models based on their characteristics. More information about the AIR system can be found in the [Models page](https://docs.runware.ai/en/image-inference/models).", + }; + + const loraWeight = { + type: "integer", + label: "LoRA Weight 0", + description: "It is possible to use multiple LoRAs at the same time. With the `weight` parameter you can assign the importance of the LoRA with respect to the others. The sum of all `weight` parameters must always be `1`. If needed, we will increase the values proportionally to achieve it.", + optional: true, + }; + + if (structure === constants.IMAGE_INFERENCE_STRUCTURE.TEXT_TO_IMAGE.value) { + return { + outputType: { + type: "string", + label: "Output Type", + description: "Specifies the output type in which the image is returned.", + optional: true, + options: [ + "base64Data", + "dataURI", + "URL", + ], + }, + outputFormat: { + type: "string", + label: "Output Format", + description: "Specifies the format of the output image.", + optional: true, + options: [ + "PNG", + "JPG", + "WEBP", + ], + }, + negativePrompt: { + type: "string", + label: "Negative Prompt", + description: "A negative prompt is a text instruction to guide the model on generating the image. It is usually a sentence or a paragraph that provides negative guidance for the task. This parameter helps to avoid certain undesired results. For example, if the negative prompt is `red dragon, cup`, the model will follow the positive prompt but will avoid generating an image of a red dragon or including a cup. The more detailed the prompt, the more accurate the results. The length of the prompt must be between 4 and 2000 characters.", + optional: true, + }, + steps: { + type: "integer", + label: "Steps", + description: "The number of steps is the number of iterations the model will perform to generate the image. The higher the number of steps, the more detailed the image will be. However, increasing the number of steps will also increase the time it takes to generate the image and may not always result in a better image (some [schedulers](https://docs.runware.ai/en/image-inference/api-reference#request-scheduler) work differently). When using your own models you can specify a new default value for the number of steps. Defaults to `20`.", + min: 1, + max: 100, + optional: true, + }, + CFGScale: { + type: "string", + label: "CFG Scale", + description: "Guidance scale represents how closely the images will resemble the prompt or how much freedom the AI model has. Higher values are closer to the prompt. Low values may reduce the quality of the results. Min: `0`, Max: `30` Default: `7`.", + optional: true, + }, + }; + } + + if (structure === constants.IMAGE_INFERENCE_STRUCTURE.IMAGE_TO_IMAGE.value) { + return { + seedImage, + strength, + }; + } + + if (structure === constants.IMAGE_INFERENCE_STRUCTURE.IN_OUT_PAINTING.value) { + return { + seedImage, + maskImage, + strength, + }; + } + + if (structure === constants.IMAGE_INFERENCE_STRUCTURE.REFINER.value) { + return { + refinerModel: { + type: "string", + label: "Refiner Model", + description: "We make use of the [AIR system](https://github.com/civitai/civitai/wiki/AIR-%E2%80%90-Uniform-Resource-Names-for-AI) to identify refinement models. This identifier is a unique string that represents a specific model. Note that refiner models are only SDXL based. You can find the AIR identifier of the refinement model you want to use in our [Model Explorer](https://docs.runware.ai/en/image-inference/models#model-explorer), which is a tool that allows you to search for models based on their characteristics. More information about the AIR system can be found in the [Models page](https://docs.runware.ai/en/image-inference/models).", + }, + refinerStartStep: { + type: "integer", + label: "Refiner Start Step", + description: "Represents the step number at which the refinement process begins. The initial model will generate the image up to this step, after which the refiner model takes over to enhance the result. It can take values from `0` (first step) to the number of [steps](https://docs.runware.ai/en/image-inference/api-reference#request-steps) specified.", + optional: true, + }, + }; + } + + if (structure === constants.IMAGE_INFERENCE_STRUCTURE.CONTROL_NET.value) { + return { + controlNetModel1: { + ...controlNetModel, + label: "Control Net Model 1", + }, + controlNetGuideImage1: { + ...controlNetGuideImage, + label: "Control Net Guide Image 1", + }, + controlNetWeight1: { + ...controlNetWeight, + label: "Control Net Weight 1", + }, + controlNetStartStep1: { + ...controlNetStartStep, + label: "Control Net Start Step 1", + }, + controlNetEndStep1: { + label: "Control Net End Step 1", + ...controlNetEndStep, + }, + controlNetControlMode1: { + ...controlNetControlMode, + label: "Control Net Control Mode 1", + }, + controlNetModel2: { + ...controlNetModel, + label: "Control Net Model 2", + optional: true, + }, + controlNetGuideImage2: { + ...controlNetGuideImage, + label: "Control Net Guide Image 2", + optional: true, + }, + controlNetWeight2: { + ...controlNetWeight, + label: "Control Net Weight 2", + optional: true, + }, + controlNetStartStep2: { + ...controlNetStartStep, + label: "Control Net Start Step 2", + optional: true, + }, + controlNetEndStep2: { + ...controlNetEndStep, + label: "Control Net End Step 2", + optional: true, + }, + controlNetControlMode2: { + ...controlNetControlMode, + label: "Control Net Control Mode 2", + optional: true, + }, + }; + } + + if (structure === constants.IMAGE_INFERENCE_STRUCTURE.LORA.value) { + return { + loraModel1: { + ...loraModel, + label: "LoRA Model 1", + }, + loraWeight1: { + label: "LoRA Weight 1", + ...loraWeight, + }, + loraModel2: { + label: "LoRA Model 2", + ...loraModel, + optional: true, + }, + loraWeight2: { + label: "LoRA Weight 2", + ...loraWeight, + }, + }; + } + + return {}; + }, + async run({ $ }) { + const { + app, + outputType, + outputFormat, + uploadEndpoint, + checkNSFW, + includeCost, + positivePrompt, + negativePrompt, + seedImage, + maskImage, + strength, + height, + width, + model, + steps, + scheduler, + seed, + numberResults, + CFGScale, + refinerModel, + refinerStartStep, + controlNetModel1, + controlNetGuideImage1, + controlNetWeight1, + controlNetStartStep1, + controlNetEndStep1, + controlNetControlMode1, + controlNetModel2, + controlNetGuideImage2, + controlNetWeight2, + controlNetStartStep2, + controlNetEndStep2, + controlNetControlMode2, + loraModel1, + loraWeight1, + loraModel2, + loraWeight2, + } = this; + + const data = { + taskType: constants.TASK_TYPE.IMAGE_INFERENCE.value, + taskUUID: uuid(), + positivePrompt, + outputType, + outputFormat, + uploadEndpoint, + checkNSFW, + includeCost, + negativePrompt, + seedImage, + maskImage, + strength, + height, + width, + model, + steps, + scheduler, + seed: seed + ? parseInt(seed) + : undefined, + numberResults, + CFGScale, + refiner: refinerModel + ? { + model: refinerModel, + startStep: refinerStartStep, + } + : undefined, + controlNet: controlNetModel1 + ? [ + { + model: controlNetModel1, + guideImage: controlNetGuideImage1, + weight: controlNetWeight1, + startStep: controlNetStartStep1, + endStep: controlNetEndStep1, + controlMode: controlNetControlMode1, + }, + ...(controlNetModel2 + ? [ + { + model: controlNetModel2, + guideImage: controlNetGuideImage2, + weight: controlNetWeight2, + startStep: controlNetStartStep2, + endStep: controlNetEndStep2, + controlMode: controlNetControlMode2, + }, + ] + : [] + ), + ] + : undefined, + lora: loraModel1 + ? [ + { + model: loraModel1, + weight: loraWeight1, + }, + ...(loraModel2 + ? [ + { + model: loraModel2, + weight: loraWeight2, + }, + ] + : [] + ), + ] + : undefined, + }; + + const response = await app.post({ + $, + data: [ + data, + ], + }); + + $.export("$summary", `Successfully requested image inference task with UUID \`${response.data[0].taskUUID}\`.`); + return response; + }, +}; diff --git a/components/runware/actions/image-upscale/image-upscale.mjs b/components/runware/actions/image-upscale/image-upscale.mjs new file mode 100644 index 0000000000000..49879c4573a71 --- /dev/null +++ b/components/runware/actions/image-upscale/image-upscale.mjs @@ -0,0 +1,73 @@ +import { v4 as uuid } from "uuid"; +import app from "../../runware.app.mjs"; +import constants from "../../common/constants.mjs"; + +export default { + key: "runware-image-upscale", + name: "Image Upscale", + description: "Request an image upscale task to be processed by the Runware API. [See the documentation](https://docs.runware.ai/en/image-editing/upscaling).", + version: "0.0.1", + type: "action", + props: { + app, + inputImage: { + propDefinition: [ + app, + "inputImage", + ], + }, + outputType: { + propDefinition: [ + app, + "outputType", + ], + }, + outputFormat: { + propDefinition: [ + app, + "outputFormat", + ], + }, + upscaleFactor: { + type: "integer", + label: "Upscale Factor", + description: "The level of upscaling performed. Each will increase the size of the image by the corresponding factor. Eg. `2`.", + min: 2, + max: 4, + }, + includeCost: { + propDefinition: [ + app, + "includeCost", + ], + }, + }, + async run({ $ }) { + const { + app, + inputImage, + outputType, + outputFormat, + upscaleFactor, + includeCost, + } = this; + + const response = await app.post({ + $, + data: [ + { + taskType: constants.TASK_TYPE.IMAGE_UPSCALE.value, + taskUUID: uuid(), + inputImage, + outputType, + outputFormat, + upscaleFactor, + includeCost, + }, + ], + }); + + $.export("$summary", `Successfully requested image upscale task with UUID \`${response.data[0].taskUUID}\`.`); + return response; + }, +}; diff --git a/components/runware/actions/prompt-enhance/prompt-enhance.mjs b/components/runware/actions/prompt-enhance/prompt-enhance.mjs new file mode 100644 index 0000000000000..0d21956a34469 --- /dev/null +++ b/components/runware/actions/prompt-enhance/prompt-enhance.mjs @@ -0,0 +1,65 @@ +import { v4 as uuid } from "uuid"; +import app from "../../runware.app.mjs"; +import constants from "../../common/constants.mjs"; + +export default { + key: "runware-prompt-enhance", + name: "Prompt Enhance", + description: "Request a prompt enhance task to be processed by the Runware API. [See the documentation](https://docs.runware.ai/en/utilities/prompt-enhancer).", + version: "0.0.1", + type: "action", + props: { + app, + prompt: { + type: "string", + label: "Prompt", + description: "The prompt that you intend to enhance.", + }, + promptMaxLength: { + type: "integer", + label: "Prompt Max Length", + description: "Represents the maximum length of the enhanced prompt that you intend to receive. Min `12`, Max `400`.", + min: 12, + max: 400, + }, + promptVersions: { + type: "integer", + label: "Prompt Versions", + description: "The number of prompt versions that will be received. Min `1`, Max `5`.", + min: 1, + max: 5, + }, + includeCost: { + propDefinition: [ + app, + "includeCost", + ], + }, + }, + async run({ $ }) { + const { + app, + prompt, + promptMaxLength, + promptVersions, + includeCost, + } = this; + + const response = await app.post({ + $, + data: [ + { + taskUUID: uuid(), + taskType: constants.TASK_TYPE.PROMPT_ENHANCE.value, + prompt, + promptMaxLength, + promptVersions, + includeCost, + }, + ], + }); + + $.export("$summary", `Successfully requested prompt enhance task with UUID \`${response.data[0].taskUUID}\`.`); + return response; + }, +}; diff --git a/components/runware/actions/request-task/request-task.mjs b/components/runware/actions/request-task/request-task.mjs deleted file mode 100644 index 509660bd5ad75..0000000000000 --- a/components/runware/actions/request-task/request-task.mjs +++ /dev/null @@ -1,176 +0,0 @@ -import { v4 as uuid } from "uuid"; -import app from "../../runware.app.mjs"; - -export default { - key: "runware-request-task", - name: "Request Task", - description: "Request one task to be processed by the Runware API. [See the documentation](https://docs.runware.ai/en/image-inference/api-reference).", - version: "0.0.1", - type: "action", - props: { - app, - taskType: { - propDefinition: [ - app, - "taskType", - ], - }, - outputType: { - propDefinition: [ - app, - "outputType", - ], - }, - outputFormat: { - propDefinition: [ - app, - "outputFormat", - ], - }, - uploadEndpoint: { - propDefinition: [ - app, - "uploadEndpoint", - ], - }, - checkNSFW: { - propDefinition: [ - app, - "checkNSFW", - ], - }, - includeCost: { - propDefinition: [ - app, - "includeCost", - ], - }, - positivePrompt: { - propDefinition: [ - app, - "positivePrompt", - ], - }, - negativePrompt: { - propDefinition: [ - app, - "negativePrompt", - ], - }, - seedImage: { - propDefinition: [ - app, - "seedImage", - ], - }, - maskImage: { - propDefinition: [ - app, - "maskImage", - ], - }, - strength: { - propDefinition: [ - app, - "strength", - ], - }, - height: { - propDefinition: [ - app, - "height", - ], - }, - width: { - propDefinition: [ - app, - "width", - ], - }, - model: { - propDefinition: [ - app, - "model", - ], - }, - steps: { - propDefinition: [ - app, - "steps", - ], - }, - scheduler: { - propDefinition: [ - app, - "scheduler", - ], - }, - seed: { - propDefinition: [ - app, - "seed", - ], - }, - numberResults: { - propDefinition: [ - app, - "numberResults", - ], - }, - }, - async run({ $ }) { - const { - app, - taskType, - outputType, - outputFormat, - uploadEndpoint, - checkNSFW, - includeCost, - positivePrompt, - negativePrompt, - seedImage, - maskImage, - strength, - height, - width, - model, - steps, - scheduler, - seed, - numberResults, - } = this; - - const response = await app.post({ - $, - data: [ - { - taskUUID: uuid(), - taskType, - outputType, - outputFormat, - uploadEndpoint, - checkNSFW, - includeCost, - positivePrompt, - negativePrompt, - seedImage, - maskImage, - strength, - height, - width, - model, - steps, - scheduler, - seed: seed - ? parseInt(seed) - : undefined, - numberResults, - }, - ], - }); - - $.export("$summary", `Successfully requested task with UUID \`${response.data[0].taskUUID}\`.`); - return response; - }, -}; diff --git a/components/runware/common/constants.mjs b/components/runware/common/constants.mjs index 01df0f6f95e74..c7e2902406234 100644 --- a/components/runware/common/constants.mjs +++ b/components/runware/common/constants.mjs @@ -28,8 +28,36 @@ const TASK_TYPE = { }, }; +const IMAGE_INFERENCE_STRUCTURE = { + TEXT_TO_IMAGE: { + value: "textToImage", + label: "Text to Image", + }, + IMAGE_TO_IMAGE: { + value: "imageToImage", + label: "Image to Image", + }, + IN_OUT_PAINTING: { + value: "inOutpainting", + label: "In/Outpainting", + }, + REFINER: { + value: "refiner", + label: "Refiner", + }, + CONTROL_NET: { + value: "controlNet", + label: "Control Net", + }, + LORA: { + value: "lora", + label: "LoRA", + }, +}; + export default { BASE_URL, VERSION_PATH, + IMAGE_INFERENCE_STRUCTURE, TASK_TYPE, }; diff --git a/components/runware/package.json b/components/runware/package.json index 02fb5aff6d31d..345513e700ef6 100644 --- a/components/runware/package.json +++ b/components/runware/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/runware", - "version": "0.1.0", + "version": "0.2.0", "description": "Pipedream Runware Components", "main": "runware.app.mjs", "keywords": [ diff --git a/components/runware/runware.app.mjs b/components/runware/runware.app.mjs index eda79b83d54b0..8fea1cf1c8ff4 100644 --- a/components/runware/runware.app.mjs +++ b/components/runware/runware.app.mjs @@ -33,53 +33,12 @@ export default { "WEBP", ], }, - uploadEndpoint: { - type: "string", - label: "Upload Endpoint", - description: "This parameter allows you to specify a URL to which the generated image will be uploaded as binary image data using the HTTP PUT method. For example, an S3 bucket URL can be used as the upload endpoint. When the image is ready, it will be uploaded to the specified URL.", - optional: true, - }, - checkNSFW: { - type: "boolean", - label: "Check NSFW", - description: "This parameter is used to enable or disable the NSFW check. When enabled, the API will check if the image contains NSFW (not safe for work) content. This check is done using a pre-trained model that detects adult content in images. When the check is enabled, the API will return `NSFWContent: true` in the response object if the image is flagged as potentially sensitive content. If the image is not flagged, the API will return `NSFWContent: false`. If this parameter is not used, the parameter `NSFWContent` will not be included in the response object. Adds `0.1` seconds to image inference time and incurs additional costs. The NSFW filter occasionally returns false positives and very rarely false negatives.", - optional: true, - }, includeCost: { type: "boolean", label: "Include Cost", description: "If set to `true`, the cost to perform the task will be included in the response object. Defaults to `false`.", optional: true, }, - positivePrompt: { - type: "string", - label: "Positive Prompt", - description: "A positive prompt is a text instruction to guide the model on generating the image. It is usually a sentence or a paragraph that provides positive guidance for the task. This parameter is essential to shape the desired results. For example, if the positive prompt is `dragon drinking coffee`, the model will generate an image of a dragon drinking coffee. The more detailed the prompt, the more accurate the results. The length of the prompt must be between 4 and 2000 characters.", - }, - negativePrompt: { - type: "string", - label: "Negative Prompt", - description: "A negative prompt is a text instruction to guide the model on generating the image. It is usually a sentence or a paragraph that provides negative guidance for the task. This parameter helps to avoid certain undesired results. For example, if the negative prompt is `red dragon, cup`, the model will follow the positive prompt but will avoid generating an image of a red dragon or including a cup. The more detailed the prompt, the more accurate the results. The length of the prompt must be between 4 and 2000 characters.", - optional: true, - }, - seedImage: { - type: "string", - label: "Seed Image", - description: "When doing Image-to-Image, Inpainting or Outpainting, this parameter is **required**. Specifies the seed image to be used for the diffusion process. The image can be specified in one of the following formats:\n - An UUID v4 string of a [previously uploaded image](https://docs.runware.ai/en/getting-started/image-upload) or a [generated image](https://docs.runware.ai/en/image-inference/api-reference).\n - A data URI string representing the image. The data URI must be in the format `data:;base64,` followed by the base64-encoded image. For example: `data:image/png;base64,iVBORw0KGgo...`.\n - A base64 encoded image without the data URI prefix. For example: `iVBORw0KGgo...`.\n - A URL pointing to the image. The image must be accessible publicly. Supported formats are: PNG, JPG and WEBP.", - optional: true, - }, - maskImage: { - type: "string", - label: "Mask Image", - description: "When doing Inpainting or Outpainting, this parameter is **required**. Specifies the mask image to be used for the inpainting process. The image can be specified in one of the following formats:\n - An UUID v4 string of a [previously uploaded image](https://docs.runware.ai/en/getting-started/image-upload) or a [generated image](https://docs.runware.ai/en/image-inference/api-reference).\n - A data URI string representing the image. The data URI must be in the format `data:;base64,` followed by the base64-encoded image. For example: `data:image/png;base64,iVBORw0KGgo...`.\n - A base64 encoded image without the data URI prefix. For example: `iVBORw0KGgo...`.\n - A URL pointing to the image. The image must be accessible publicly. Supported formats are: PNG, JPG and WEBP.", - optional: true, - }, - strength: { - type: "string", - label: "Strength", - description: "When doing Image-to-Image, Inpainting or Outpainting, this parameter is used to determine the influence of the **Seed Image** image in the generated output. A higher value results in more influence from the original image, while a lower value allows more creative deviation. Min: `0` Max: `1` and Default: `0.8`.", - optional: true, - }, height: { type: "integer", label: "Height", @@ -94,36 +53,10 @@ export default { min: 512, max: 2048, }, - model: { - type: "string", - label: "Model", - description: "This identifier is a unique string that represents a specific model. You can find the AIR identifier of the model you want to use in our [Model Explorer](https://docs.runware.ai/en/image-inference/models#model-explorer), which is a tool that allows you to search for models based on their characteristics. More information about the AIR system can be found in the [Models page](https://docs.runware.ai/en/image-inference/models). Eg. `civitai:78605@83390`.", - }, - steps: { - type: "integer", - label: "Steps", - description: "The number of steps is the number of iterations the model will perform to generate the image. The higher the number of steps, the more detailed the image will be. However, increasing the number of steps will also increase the time it takes to generate the image and may not always result in a better image (some [schedulers](https://docs.runware.ai/en/image-inference/api-reference#request-scheduler) work differently). When using your own models you can specify a new default value for the number of steps. Defaults to `20`.", - min: 1, - max: 100, - optional: true, - }, - scheduler: { - type: "string", - label: "Scheduler", - description: "An scheduler is a component that manages the inference process. Different schedulers can be used to achieve different results like more detailed images, faster inference, or more accurate results. The default scheduler is the one that the model was trained with, but you can choose a different one to get different results. Schedulers are explained in more detail in the [Schedulers page](https://docs.runware.ai/en/image-inference/schedulers).", - optional: true, - }, - seed: { + inputImage: { type: "string", - label: "Seed", - description: "A seed is a value used to randomize the image generation. If you want to make images reproducible (generate the same image multiple times), you can use the same seed value. When requesting multiple images with the same seed, the seed will be incremented by 1 (+1) for each image generated. Min: `0` Max: `9223372036854776000`. Defaults to `Random`.", - optional: true, - }, - numberResults: { - type: "integer", - label: "Number Of Results", - description: "The number of images to generate from the specified prompt. If **Seed** is set, it will be incremented by 1 (+1) for each image generated.", - optional: true, + label: "Input Image", + description: "Specifies the input image to be processed. The image can be specified in one of the following formats:\n - An UUID v4 string of a [previously uploaded image](https://docs.runware.ai/en/getting-started/image-upload) or a [generated image](https://docs.runware.ai/en/image-inference/api-reference).\n - A data URI string representing the image. The data URI must be in the format `data:;base64,` followed by the base64-encoded image. For example: `data:image/png;base64,iVBORw0KGgo...`.\n - A base64 encoded image without the data URI prefix. For example: `iVBORw0KGgo...`.\n - A URL pointing to the image. The image must be accessible publicly.\nSupported formats are: PNG, JPG and WEBP.", }, }, methods: {