Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../../../.eslintrc.base.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-comfyicu
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-comfyicu` to build the library.
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@activepieces/piece-comfyicu",
|
||||
"version": "0.0.5"
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "pieces-comfyicu",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/comfyicu/src",
|
||||
"projectType": "library",
|
||||
"release": {
|
||||
"version": {
|
||||
"currentVersionResolver": "git-tag",
|
||||
"preserveLocalDependencyProtocols": false,
|
||||
"manifestRootsToUpdate": [
|
||||
"dist/{projectRoot}"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/comfyicu",
|
||||
"tsConfig": "packages/pieces/community/comfyicu/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/comfyicu/package.json",
|
||||
"main": "packages/pieces/community/comfyicu/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/comfyicu/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/comfyicu/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"nx-release-publish": {
|
||||
"options": {
|
||||
"packageRoot": "dist/{projectRoot}"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/comfyicu",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"You can obtain API key from [Account Settings](https://comfy.icu/account).": "Sie können den API-Schlüssel unter [Kontoeinstellungen](https://comfy.icu/account).",
|
||||
"Get Run Output": "Starte Ausgabe",
|
||||
"Get Run Status": "Start-Status erhalten",
|
||||
"List Workflows": "Workflows auflisten",
|
||||
"Submit Workflow Run": "Workflow-Run absenden",
|
||||
"Retrieves generated images or videos from a completed run.": "Ruft generierte Bilder oder Videos von einem abgeschlossenen Lauf ab.",
|
||||
"Retrieves the status of workflow run.": "Ruft den Status des Workflows ab.",
|
||||
"Retrieves available workflows for execution.": "Ruft verfügbare Workflows für die Ausführung ab.",
|
||||
"Execute a workflow with specified prompt.": "Führen Sie einen Workflow mit der angegebenen Abfrage aus.",
|
||||
"Workflow ID": "Workflow-ID",
|
||||
"Run ID": "Ausführen ID",
|
||||
"Prompt": "Prompt",
|
||||
"Webhook": "Webhook",
|
||||
"You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.": "Sie können einen Workflow-Prompt erhalten, indem Sie unter History->Auswahl Ausführen -> API Workflow kopieren.",
|
||||
"Webhook URL to recieve run status.": "Webhook URL um den Ausführungsstatus zu erhalten.",
|
||||
"New Workflow Created": "Neuer Workflow erstellt",
|
||||
"Run Completed": "Ausführung abgeschlossen",
|
||||
"Run Failed": "Ausführung fehlgeschlagen",
|
||||
"Triggers when a new workflow is created.": "Wird ausgelöst, wenn ein neuer Workflow erstellt wird.",
|
||||
"Triggers when a workflow run is successfully completed.": "Wird ausgelöst, wenn ein Workflow erfolgreich abgeschlossen wurde.",
|
||||
"Triggers when a workflow run is failed.": "Wird ausgelöst, wenn ein Workflow-Lauf fehlgeschlagen ist."
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"You can obtain API key from [Account Settings](https://comfy.icu/account).": "Puedes obtener la clave API de [Configuración de la cuenta](https://comfy.icu/account).",
|
||||
"Get Run Output": "Obtener salida",
|
||||
"Get Run Status": "Obtener estado de ejecución",
|
||||
"List Workflows": "Listar flujos de trabajo",
|
||||
"Submit Workflow Run": "Enviar ejecución de flujo de trabajo",
|
||||
"Retrieves generated images or videos from a completed run.": "Recuperar imágenes o videos generados desde una ejecución completada.",
|
||||
"Retrieves the status of workflow run.": "Recuperar el estado de ejecución del flujo de trabajo.",
|
||||
"Retrieves available workflows for execution.": "Recuperar flujos de trabajo disponibles para su ejecución.",
|
||||
"Execute a workflow with specified prompt.": "Ejecutar un flujo de trabajo con un indicador especificado.",
|
||||
"Workflow ID": "ID de flujo de trabajo",
|
||||
"Run ID": "Ejecutar ID",
|
||||
"Prompt": "Petición",
|
||||
"Webhook": "Webhook",
|
||||
"You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.": "Puede obtener el indicador de flujo de trabajo navegando a Historia->Seleccione Ejecutar-> Copiar flujo de trabajo API.",
|
||||
"Webhook URL to recieve run status.": "Webhook URL para recibir el estado de ejecución.",
|
||||
"New Workflow Created": "Nuevo flujo de trabajo creado",
|
||||
"Run Completed": "Ejecutar completado",
|
||||
"Run Failed": "Error al ejecutar",
|
||||
"Triggers when a new workflow is created.": "Dispara cuando se crea un nuevo flujo de trabajo.",
|
||||
"Triggers when a workflow run is successfully completed.": "Se activa cuando un flujo de trabajo se ejecuta correctamente.",
|
||||
"Triggers when a workflow run is failed.": "Dispara cuando un flujo de trabajo falla."
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"You can obtain API key from [Account Settings](https://comfy.icu/account).": "Vous pouvez obtenir la clé API dans [Paramètres du compte](https://comfy.icu/account).",
|
||||
"Get Run Output": "Obtenir la sortie d'exécution",
|
||||
"Get Run Status": "Obtenir le statut d'exécution",
|
||||
"List Workflows": "Lister les Workflows",
|
||||
"Submit Workflow Run": "Soumettre l'exécution du flux de travail",
|
||||
"Retrieves generated images or videos from a completed run.": "Récupère des images ou des vidéos générées à partir d'une exécution terminée.",
|
||||
"Retrieves the status of workflow run.": "Récupère le statut de l'exécution du workflow.",
|
||||
"Retrieves available workflows for execution.": "Récupère les workflows disponibles pour l'exécution.",
|
||||
"Execute a workflow with specified prompt.": "Exécute un workflow avec l'invite spécifiée.",
|
||||
"Workflow ID": "ID du flux de travail",
|
||||
"Run ID": "Lancer l'ID",
|
||||
"Prompt": "Prompt",
|
||||
"Webhook": "Webhook",
|
||||
"You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.": "Vous pouvez obtenir l'invite de workflow en accédant à History->Select Run -> Copy API Workflow.",
|
||||
"Webhook URL to recieve run status.": "URL du Webhook pour recevoir le statut de l'exécution.",
|
||||
"New Workflow Created": "Nouveau Workflow créé",
|
||||
"Run Completed": "Exécution terminée",
|
||||
"Run Failed": "Run Failed",
|
||||
"Triggers when a new workflow is created.": "Déclenche lorsqu'un nouveau workflow est créé.",
|
||||
"Triggers when a workflow run is successfully completed.": "Déclenche lorsqu'un workflow est exécuté avec succès.",
|
||||
"Triggers when a workflow run is failed.": "Déclenche lorsqu'un workflow est exécuté en échec."
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"You can obtain API key from [Account Settings](https://comfy.icu/account).": "[アカウント設定](https://comfy.icu/account)からAPIキーを取得できます。",
|
||||
"Get Run Output": "実行出力を取得",
|
||||
"Get Run Status": "実行状況を取得する",
|
||||
"List Workflows": "ワークフローの一覧",
|
||||
"Submit Workflow Run": "ワークフロー実行を送信",
|
||||
"Retrieves generated images or videos from a completed run.": "完了した実行から生成された画像や動画を取得します。",
|
||||
"Retrieves the status of workflow run.": "ワークフローの実行の状態を取得します。",
|
||||
"Retrieves available workflows for execution.": "実行のために利用可能なワークフローを取得します。",
|
||||
"Execute a workflow with specified prompt.": "指定したプロンプトでワークフローを実行します。",
|
||||
"Workflow ID": "ワークフロー ID",
|
||||
"Run ID": "実行 ID",
|
||||
"Prompt": "Prompt",
|
||||
"Webhook": "Webhook",
|
||||
"You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.": "History->format@@0->format@@1->format@@2ワークフローをコピーすることで、ワークフロープロンプトを取得できます。",
|
||||
"Webhook URL to recieve run status.": "実行ステータスを受け取るWebhookのURL。",
|
||||
"New Workflow Created": "新しいワークフローを作成しました",
|
||||
"Run Completed": "実行完了",
|
||||
"Run Failed": "実行に失敗しました",
|
||||
"Triggers when a new workflow is created.": "新しいワークフローが作成されたときにトリガーします。",
|
||||
"Triggers when a workflow run is successfully completed.": "ワークフローの実行が正常に完了したときにトリガーします。",
|
||||
"Triggers when a workflow run is failed.": "ワークフローの実行に失敗したときにトリガーします。"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"You can obtain API key from [Account Settings](https://comfy.icu/account).": "U kunt API-sleutel verkrijgen via [Accountinstellingen](https://comfy.icu/account).",
|
||||
"Get Run Output": "Krijg Run Output",
|
||||
"Get Run Status": "Uitvoerstatus krijgen",
|
||||
"List Workflows": "Lijst Workflows",
|
||||
"Submit Workflow Run": "Indienen Workflow Run",
|
||||
"Retrieves generated images or videos from a completed run.": "Ophalen gegenereerde afbeeldingen of video's van een voltooide uitvoering.",
|
||||
"Retrieves the status of workflow run.": "Haalt de status van de workflow op.",
|
||||
"Retrieves available workflows for execution.": "Ophalen beschikbare workflows voor uitvoering.",
|
||||
"Execute a workflow with specified prompt.": "Voer een workflow uit met een bepaald prompt.",
|
||||
"Workflow ID": "Workflow ID",
|
||||
"Run ID": "ID uitvoeren",
|
||||
"Prompt": "Prompt",
|
||||
"Webhook": "Webhook",
|
||||
"You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.": "U kunt workflow prompt krijgen door te navigeren naar Geschiedenis>Selecteer Uitvoer-> Kopieer API Workflow.",
|
||||
"Webhook URL to recieve run status.": "Webhook URL om uitvoeringsstatus te ontvangen.",
|
||||
"New Workflow Created": "Nieuwe Workflow aangemaakt",
|
||||
"Run Completed": "Uitvoeren voltooid",
|
||||
"Run Failed": "Run Mislukt",
|
||||
"Triggers when a new workflow is created.": "Triggert wanneer een nieuwe workflow wordt gemaakt.",
|
||||
"Triggers when a workflow run is successfully completed.": "Triggert wanneer een workflow met succes wordt uitgevoerd.",
|
||||
"Triggers when a workflow run is failed.": "Triggert wanneer een workflow wordt uitgevoerd."
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"You can obtain API key from [Account Settings](https://comfy.icu/account).": "Você pode obter uma chave de API em [Configurações da Conta](https://comfy.icu/account).",
|
||||
"Get Run Output": "Obter saída de execução",
|
||||
"Get Run Status": "Obter status de execução",
|
||||
"List Workflows": "Listar Workflows",
|
||||
"Submit Workflow Run": "Enviar execução de workflow",
|
||||
"Retrieves generated images or videos from a completed run.": "Obtém imagens geradas ou vídeos de uma execução completa.",
|
||||
"Retrieves the status of workflow run.": "Recupera o status da execução do fluxo de trabalho.",
|
||||
"Retrieves available workflows for execution.": "Recupera fluxos de trabalho disponíveis para execução.",
|
||||
"Execute a workflow with specified prompt.": "Executa um fluxo de trabalho com um prompt especificado.",
|
||||
"Workflow ID": "ID do workflow",
|
||||
"Run ID": "Executar ID",
|
||||
"Prompt": "Aviso",
|
||||
"Webhook": "Webhook",
|
||||
"You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.": "Você pode obter a notificação de fluxo de trabalho navegando até o Histórico>Selecione Executar -> Copiar fluxo de trabalho da API.",
|
||||
"Webhook URL to recieve run status.": "URL do Webhook para receber o status do executar.",
|
||||
"New Workflow Created": "Novo workflow criado",
|
||||
"Run Completed": "Execução concluída",
|
||||
"Run Failed": "Execução Falhou",
|
||||
"Triggers when a new workflow is created.": "Dispara quando um novo fluxo de trabalho é criado.",
|
||||
"Triggers when a workflow run is successfully completed.": "Dispara quando uma execução do fluxo de trabalho for concluída com êxito.",
|
||||
"Triggers when a workflow run is failed.": "Aciona quando a execução de um fluxo de trabalho falhou."
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"Comfy.ICU": "Comfy.ICU",
|
||||
"You can obtain API key from [Account Settings](https://comfy.icu/account).": "Вы можете получить ключ API в [Настройках аккаунта](https://comfy.icu/account).",
|
||||
"Get Run Output": "Запустить вывод",
|
||||
"Get Run Status": "Получить статус запуска",
|
||||
"List Workflows": "Список рабочих процессов",
|
||||
"Submit Workflow Run": "Отправить запуск рабочего процесса",
|
||||
"Retrieves generated images or videos from a completed run.": "Получает сгенерированные изображения или видео из завершённого запуска.",
|
||||
"Retrieves the status of workflow run.": "Получает статус выполнения рабочего процесса.",
|
||||
"Retrieves available workflows for execution.": "Получает доступные рабочие процессы для выполнения.",
|
||||
"Execute a workflow with specified prompt.": "Выполнить рабочий процесс с указанной подсказкой.",
|
||||
"Workflow ID": "ID рабочего процесса",
|
||||
"Run ID": "ID запуска",
|
||||
"Prompt": "Prompt",
|
||||
"Webhook": "Вебхук",
|
||||
"You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.": "Вы можете получить запрос рабочего процесса, перейдя по ссылке History->Select Run -> Copy API Workflow.",
|
||||
"Webhook URL to recieve run status.": "Webhook URL для получения статуса запуска.",
|
||||
"New Workflow Created": "Новый рабочий процесс создан",
|
||||
"Run Completed": "Запуск завершен",
|
||||
"Run Failed": "Неудачный запуск",
|
||||
"Triggers when a new workflow is created.": "Триггеры при создании нового рабочего процесса.",
|
||||
"Triggers when a workflow run is successfully completed.": "Триггеры при запуске рабочего процесса успешно завершены.",
|
||||
"Triggers when a workflow run is failed.": "Триггеры, когда рабочий процесс не запущен."
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"You can obtain API key from [Account Settings](https://comfy.icu/account).": "You can obtain API key from [Account Settings](https://comfy.icu/account).",
|
||||
"Get Run Output": "Get Run Output",
|
||||
"Get Run Status": "Get Run Status",
|
||||
"List Workflows": "List Workflows",
|
||||
"Submit Workflow Run": "Submit Workflow Run",
|
||||
"Retrieves generated images or videos from a completed run.": "Retrieves generated images or videos from a completed run.",
|
||||
"Retrieves the status of workflow run.": "Retrieves the status of workflow run.",
|
||||
"Retrieves available workflows for execution.": "Retrieves available workflows for execution.",
|
||||
"Execute a workflow with specified prompt.": "Execute a workflow with specified prompt.",
|
||||
"Workflow ID": "Workflow ID",
|
||||
"Run ID": "Run ID",
|
||||
"Prompt": "Prompt",
|
||||
"Webhook": "Webhook",
|
||||
"You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.": "You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.",
|
||||
"Webhook URL to recieve run status.": "Webhook URL to recieve run status.",
|
||||
"New Workflow Created": "New Workflow Created",
|
||||
"Run Completed": "Run Completed",
|
||||
"Run Failed": "Run Failed",
|
||||
"Triggers when a new workflow is created.": "Triggers when a new workflow is created.",
|
||||
"Triggers when a workflow run is successfully completed.": "Triggers when a workflow run is successfully completed.",
|
||||
"Triggers when a workflow run is failed.": "Triggers when a workflow run is failed."
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"Comfy.ICU": "Comfy.ICU",
|
||||
"You can obtain API key from [Account Settings](https://comfy.icu/account).": "You can obtain API key from [Account Settings](https://comfy.icu/account).",
|
||||
"Get Run Output": "Get Run Output",
|
||||
"Get Run Status": "Get Run Status",
|
||||
"List Workflows": "List Workflows",
|
||||
"Submit Workflow Run": "Submit Workflow Run",
|
||||
"Retrieves generated images or videos from a completed run.": "Retrieves generated images or videos from a completed run.",
|
||||
"Retrieves the status of workflow run.": "Retrieves the status of workflow run.",
|
||||
"Retrieves available workflows for execution.": "Retrieves available workflows for execution.",
|
||||
"Execute a workflow with specified prompt.": "Execute a workflow with specified prompt.",
|
||||
"Workflow ID": "Workflow ID",
|
||||
"Run ID": "Run ID",
|
||||
"Prompt": "Prompt",
|
||||
"Webhook": "Webhook",
|
||||
"You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.": "You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.",
|
||||
"Webhook URL to recieve run status.": "Webhook URL to recieve run status.",
|
||||
"New Workflow Created": "New Workflow Created",
|
||||
"Run Completed": "Run Completed",
|
||||
"Run Failed": "Run Failed",
|
||||
"Triggers when a new workflow is created.": "Triggers when a new workflow is created.",
|
||||
"Triggers when a workflow run is successfully completed.": "Triggers when a workflow run is successfully completed.",
|
||||
"Triggers when a workflow run is failed.": "Triggers when a workflow run is failed."
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"You can obtain API key from [Account Settings](https://comfy.icu/account).": "You can obtain API key from [Account Settings](https://comfy.icu/account).",
|
||||
"Get Run Output": "Get Run Output",
|
||||
"Get Run Status": "Get Run Status",
|
||||
"List Workflows": "List Workflows",
|
||||
"Submit Workflow Run": "Submit Workflow Run",
|
||||
"Retrieves generated images or videos from a completed run.": "Retrieves generated images or videos from a completed run.",
|
||||
"Retrieves the status of workflow run.": "Retrieves the status of workflow run.",
|
||||
"Retrieves available workflows for execution.": "Retrieves available workflows for execution.",
|
||||
"Execute a workflow with specified prompt.": "Execute a workflow with specified prompt.",
|
||||
"Workflow ID": "Workflow ID",
|
||||
"Run ID": "Run ID",
|
||||
"Prompt": "Prompt",
|
||||
"Webhook": "Webhook",
|
||||
"You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.": "You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.",
|
||||
"Webhook URL to recieve run status.": "Webhook URL to recieve run status.",
|
||||
"New Workflow Created": "New Workflow Created",
|
||||
"Run Completed": "Run Completed",
|
||||
"Run Failed": "运行失败",
|
||||
"Triggers when a new workflow is created.": "Triggers when a new workflow is created.",
|
||||
"Triggers when a workflow run is successfully completed.": "Triggers when a workflow run is successfully completed.",
|
||||
"Triggers when a workflow run is failed.": "Triggers when a workflow run is failed."
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
import { getRunOutputAction } from './lib/actions/get-run-outputs';
|
||||
import { getRunStatusAction } from './lib/actions/get-run-status';
|
||||
import { listWorkflowsAction } from './lib/actions/list-workflows';
|
||||
import { submitWorkflowRunAction } from './lib/actions/submit-workflow-run';
|
||||
import { newWorkflowCreatedTrigger } from './lib/triggers/new-workflow-created';
|
||||
import { runCompletedTrigger } from './lib/triggers/run-completed';
|
||||
import { runFailedTrigger } from './lib/triggers/run-failed';
|
||||
|
||||
export const comfyIcuAuth = PieceAuth.SecretText({
|
||||
displayName: 'API Key',
|
||||
required: true,
|
||||
description: `You can obtain API key from [Account Settings](https://comfy.icu/account).`,
|
||||
});
|
||||
|
||||
export const comfyicu = createPiece({
|
||||
displayName: 'Comfy.ICU',
|
||||
categories: [PieceCategory.ARTIFICIAL_INTELLIGENCE],
|
||||
auth: comfyIcuAuth,
|
||||
minimumSupportedRelease: '0.36.1',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/comfyicu.png',
|
||||
authors: ['rimjhimyadav'],
|
||||
actions: [getRunOutputAction,getRunStatusAction,listWorkflowsAction,submitWorkflowRunAction],
|
||||
triggers: [newWorkflowCreatedTrigger,runCompletedTrigger,runFailedTrigger],
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { comfyIcuAuth } from '../../index';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { comfyIcuApiCall, commonProps } from '../common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const getRunOutputAction = createAction({
|
||||
auth: comfyIcuAuth,
|
||||
name: 'get-run-output',
|
||||
displayName: 'Get Run Output',
|
||||
description: 'Retrieves generated images or videos from a completed run.',
|
||||
props: {
|
||||
...commonProps,
|
||||
},
|
||||
async run(context) {
|
||||
const { workflow_id, run_id } = context.propsValue;
|
||||
const response = await comfyIcuApiCall({
|
||||
apiKey: context.auth,
|
||||
endpoint: `/workflows/${workflow_id}/runs/${run_id}`,
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
|
||||
const runOutput = response.body as { output: Array<Record<string,any>> };
|
||||
return { result: runOutput.output };
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { comfyIcuAuth } from '../../index';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { comfyIcuApiCall, commonProps } from '../common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const getRunStatusAction = createAction({
|
||||
auth: comfyIcuAuth,
|
||||
name: 'get-run-status',
|
||||
displayName: 'Get Run Status',
|
||||
description: 'Retrieves the status of workflow run.',
|
||||
props: {
|
||||
...commonProps,
|
||||
},
|
||||
async run(context) {
|
||||
const { workflow_id, run_id } = context.propsValue;
|
||||
const response = await comfyIcuApiCall({
|
||||
apiKey: context.auth,
|
||||
endpoint: `/workflows/${workflow_id}/runs/${run_id}`,
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
|
||||
const runStatus = response.body as { status: string };
|
||||
return { status: runStatus.status };
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
import { comfyIcuAuth } from '../../index';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { comfyIcuApiCall } from '../common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const listWorkflowsAction = createAction({
|
||||
auth: comfyIcuAuth,
|
||||
name: 'list-workflows',
|
||||
displayName: 'List Workflows',
|
||||
description: 'Retrieves available workflows for execution.',
|
||||
props: {},
|
||||
async run(context) {
|
||||
const response = await comfyIcuApiCall({
|
||||
apiKey: context.auth,
|
||||
endpoint: '/workflows',
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { comfyIcuAuth } from '../../index';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { comfyIcuApiCall, commonProps } from '../common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const submitWorkflowRunAction = createAction({
|
||||
auth: comfyIcuAuth,
|
||||
name: 'submit-workflow-run',
|
||||
displayName: 'Submit Workflow Run',
|
||||
description: 'Execute a workflow with specified prompt.',
|
||||
props: {
|
||||
workflow_id:commonProps.workflow_id,
|
||||
prompt:Property.Json({
|
||||
displayName:'Prompt',
|
||||
description:'You can get workflow prompt by navigating to History->Select Run -> Copy API Workflow.',
|
||||
required:true
|
||||
}),
|
||||
webhook:Property.ShortText({
|
||||
displayName:'Webhook',
|
||||
required:false,
|
||||
description:'Webhook URL to recieve run status.'
|
||||
})
|
||||
},
|
||||
async run(context) {
|
||||
const { workflow_id, prompt,webhook } = context.propsValue;
|
||||
const response = await comfyIcuApiCall({
|
||||
apiKey: context.auth,
|
||||
endpoint: `/workflows/${workflow_id}/runs`,
|
||||
method: HttpMethod.POST,
|
||||
body:{
|
||||
prompt,
|
||||
webhook
|
||||
}
|
||||
});
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
import {
|
||||
HttpMethod,
|
||||
QueryParams,
|
||||
httpClient,
|
||||
HttpRequest,
|
||||
AuthenticationType,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { AppConnectionValueForAuthProperty, Property } from '@activepieces/pieces-framework';
|
||||
import { comfyIcuAuth } from '../..';
|
||||
|
||||
export async function comfyIcuApiCall({
|
||||
apiKey: {secret_text},
|
||||
endpoint,
|
||||
method,
|
||||
qparams,
|
||||
body,
|
||||
}: {
|
||||
apiKey: AppConnectionValueForAuthProperty<typeof comfyIcuAuth>;
|
||||
endpoint: string;
|
||||
method: HttpMethod;
|
||||
qparams?: QueryParams;
|
||||
body?: any;
|
||||
}) {
|
||||
const request: HttpRequest = {
|
||||
url: `https://comfy.icu/api/v1${endpoint}`,
|
||||
method,
|
||||
queryParams: qparams,
|
||||
body,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: secret_text,
|
||||
},
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest(request);
|
||||
return response;
|
||||
}
|
||||
|
||||
export const commonProps = {
|
||||
workflow_id:Property.Dropdown({
|
||||
auth: comfyIcuAuth,
|
||||
displayName:'Workflow ID',
|
||||
refreshers:[],
|
||||
required:true,
|
||||
options:async ({auth})=>{
|
||||
if(!auth)
|
||||
{
|
||||
return{
|
||||
disabled:true,
|
||||
options:[],
|
||||
placeholder:'Please connect your account first.'
|
||||
}
|
||||
}
|
||||
|
||||
const response = await comfyIcuApiCall({
|
||||
apiKey:auth,
|
||||
endpoint:'/workflows',
|
||||
method:HttpMethod.GET
|
||||
})
|
||||
|
||||
const workflows = response.body as {id:string,name:string}[];
|
||||
|
||||
return {
|
||||
disabled:false,
|
||||
options:workflows.map((workflow)=>{
|
||||
return{
|
||||
label:workflow.name,
|
||||
value:workflow.id
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}),
|
||||
run_id:Property.ShortText({
|
||||
displayName:'Run ID',
|
||||
required:true
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import {
|
||||
DedupeStrategy,
|
||||
HttpMethod,
|
||||
Polling,
|
||||
pollingHelper,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { comfyIcuAuth } from '../../index';
|
||||
import {
|
||||
AppConnectionValueForAuthProperty,
|
||||
createTrigger,
|
||||
PiecePropValueSchema,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { comfyIcuApiCall } from '../common';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
export const newWorkflowCreatedTrigger = createTrigger({
|
||||
auth: comfyIcuAuth,
|
||||
name: 'new-workflow-created',
|
||||
displayName: 'New Workflow Created',
|
||||
description: 'Triggers when a new workflow is created.',
|
||||
type: TriggerStrategy.POLLING,
|
||||
props: {},
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
sampleData: {
|
||||
id: 'RKhLj7NZrWL7Yhk_lzEf7',
|
||||
name: 'Test Flow',
|
||||
description: null,
|
||||
created_at: '2025-05-23T14:34:16.610Z',
|
||||
updated_at: '2025-05-23T14:35:11.052Z',
|
||||
tags: [],
|
||||
is_nsfw: false,
|
||||
visibility: 'PUBLIC',
|
||||
user_id: 'xyz',
|
||||
current_run_id: 'H8fwBSWw_SJtn4hrfbsbb',
|
||||
models: null,
|
||||
accelerator: null,
|
||||
project_id: 12297,
|
||||
deleted_at: null,
|
||||
featuredImages: [],
|
||||
},
|
||||
});
|
||||
|
||||
const polling: Polling<
|
||||
AppConnectionValueForAuthProperty<typeof comfyIcuAuth>,
|
||||
Record<string, any>
|
||||
> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
async items({ auth }) {
|
||||
const response = await comfyIcuApiCall({
|
||||
apiKey: auth,
|
||||
endpoint: '/workflows',
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
|
||||
const workflows = response.body as {
|
||||
id: string;
|
||||
name: string;
|
||||
created_at: string;
|
||||
}[];
|
||||
|
||||
return workflows.map((workflow) => {
|
||||
return {
|
||||
epochMilliSeconds: dayjs(workflow.created_at).valueOf(),
|
||||
data: workflow,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,493 @@
|
||||
import { comfyIcuAuth } from '../../index';
|
||||
import {
|
||||
AppConnectionValueForAuthProperty,
|
||||
createTrigger,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { comfyIcuApiCall, commonProps } from '../common';
|
||||
import {
|
||||
DedupeStrategy,
|
||||
HttpMethod,
|
||||
Polling,
|
||||
pollingHelper,
|
||||
} from '@activepieces/pieces-common';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const polling: Polling<
|
||||
AppConnectionValueForAuthProperty<typeof comfyIcuAuth>,
|
||||
{ workflow_id: string }
|
||||
> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
async items({ auth, propsValue, lastFetchEpochMS }) {
|
||||
const { workflow_id } = propsValue;
|
||||
const listRunsResponse = await comfyIcuApiCall({
|
||||
apiKey: auth,
|
||||
endpoint: `/workflows/${workflow_id}/runs`,
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
|
||||
const runs = listRunsResponse.body as {
|
||||
id: string;
|
||||
status: string;
|
||||
created_at: string;
|
||||
}[];
|
||||
|
||||
const result = [];
|
||||
|
||||
for (const run of runs) {
|
||||
if (run.status === 'COMPLETED') {
|
||||
const runDetailsResponse = await comfyIcuApiCall({
|
||||
apiKey: auth,
|
||||
endpoint: `/workflows/${workflow_id}/runs/${run.id}`,
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
const runDetail = runDetailsResponse.body as { created_at: string };
|
||||
result.push(runDetail);
|
||||
}
|
||||
if (lastFetchEpochMS === 0 && result.length === 5) break;
|
||||
}
|
||||
|
||||
return result.map((run) => {
|
||||
return {
|
||||
epochMilliSeconds: dayjs(run.created_at).valueOf(),
|
||||
data: run,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const runCompletedTrigger = createTrigger({
|
||||
auth: comfyIcuAuth,
|
||||
name: 'run-completed',
|
||||
displayName: 'Run Completed',
|
||||
description: 'Triggers when a workflow run is successfully completed.',
|
||||
props: {
|
||||
workflow_id: commonProps.workflow_id,
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
sampleData: {
|
||||
id: 'CNCr5a_lu6g9Nz3gqKC9P',
|
||||
created_at: '2025-05-23T15:08:18.297Z',
|
||||
updated_at: '2025-05-23T15:08:27.476Z',
|
||||
deleted_at: null,
|
||||
started_at: '2025-05-23T15:08:19.760Z',
|
||||
completed_at: '2025-05-23T15:08:27.384Z',
|
||||
run_time: 6357,
|
||||
status: 'COMPLETED',
|
||||
kind: 'comfyui',
|
||||
data: {
|
||||
prompt: {
|
||||
'3': {
|
||||
_meta: {
|
||||
title: 'KSampler',
|
||||
},
|
||||
inputs: {
|
||||
cfg: 8,
|
||||
seed: 253353381004563,
|
||||
model: ['4', 0],
|
||||
steps: 20,
|
||||
denoise: 1,
|
||||
negative: ['7', 0],
|
||||
positive: ['6', 0],
|
||||
scheduler: 'normal',
|
||||
latent_image: ['5', 0],
|
||||
sampler_name: 'euler',
|
||||
},
|
||||
class_type: 'KSampler',
|
||||
},
|
||||
'4': {
|
||||
_meta: {
|
||||
title: 'Load Checkpoint',
|
||||
},
|
||||
inputs: {
|
||||
ckpt_name: 'v1-5-pruned-emaonly-fp16.safetensors',
|
||||
},
|
||||
class_type: 'CheckpointLoaderSimple',
|
||||
},
|
||||
'5': {
|
||||
_meta: {
|
||||
title: 'Empty Latent Image',
|
||||
},
|
||||
inputs: {
|
||||
width: 512,
|
||||
height: 512,
|
||||
batch_size: 1,
|
||||
},
|
||||
class_type: 'EmptyLatentImage',
|
||||
},
|
||||
'6': {
|
||||
_meta: {
|
||||
title: 'CLIP Text Encode (Prompt)',
|
||||
},
|
||||
inputs: {
|
||||
clip: ['4', 1],
|
||||
text: 'beautiful scenery nature glass bottle landscape, , purple galaxy bottle,',
|
||||
},
|
||||
class_type: 'CLIPTextEncode',
|
||||
},
|
||||
'7': {
|
||||
_meta: {
|
||||
title: 'CLIP Text Encode (Prompt)',
|
||||
},
|
||||
inputs: {
|
||||
clip: ['4', 1],
|
||||
text: 'text, watermark',
|
||||
},
|
||||
class_type: 'CLIPTextEncode',
|
||||
},
|
||||
'8': {
|
||||
_meta: {
|
||||
title: 'VAE Decode',
|
||||
},
|
||||
inputs: {
|
||||
vae: ['4', 2],
|
||||
samples: ['3', 0],
|
||||
},
|
||||
class_type: 'VAEDecode',
|
||||
},
|
||||
'9': {
|
||||
_meta: {
|
||||
title: 'Save Image',
|
||||
},
|
||||
inputs: {
|
||||
images: ['8', 0],
|
||||
filename_prefix: 'ComfyUI',
|
||||
},
|
||||
class_type: 'SaveImage',
|
||||
},
|
||||
},
|
||||
extra_data: {
|
||||
extra_pnginfo: {
|
||||
workflow: {
|
||||
extra: {
|
||||
ds: {
|
||||
scale: 0.45,
|
||||
offset: [],
|
||||
},
|
||||
ue_links: [],
|
||||
VHS_MetadataImage: true,
|
||||
VHS_latentpreview: false,
|
||||
VHS_KeepIntermediate: true,
|
||||
VHS_latentpreviewrate: 0,
|
||||
},
|
||||
links: [
|
||||
[1, 4, 0, 3, 0, 'MODEL'],
|
||||
[2, 5, 0, 3, 3, 'LATENT'],
|
||||
[3, 4, 1, 6, 0, 'CLIP'],
|
||||
[4, 6, 0, 3, 1, 'CONDITIONING'],
|
||||
[5, 4, 1, 7, 0, 'CLIP'],
|
||||
[6, 7, 0, 3, 2, 'CONDITIONING'],
|
||||
[7, 3, 0, 8, 0, 'LATENT'],
|
||||
[8, 4, 2, 8, 1, 'VAE'],
|
||||
[9, 8, 0, 9, 0, 'IMAGE'],
|
||||
],
|
||||
nodes: [
|
||||
{
|
||||
id: 7,
|
||||
pos: [413, 389],
|
||||
mode: 0,
|
||||
size: [],
|
||||
type: 'CLIPTextEncode',
|
||||
flags: {},
|
||||
order: 3,
|
||||
inputs: [
|
||||
{
|
||||
link: 5,
|
||||
name: 'clip',
|
||||
type: 'CLIP',
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'CONDITIONING',
|
||||
type: 'CONDITIONING',
|
||||
links: [6],
|
||||
slot_index: 0,
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
'Node name for S&R': 'CLIPTextEncode',
|
||||
},
|
||||
widgets_values: ['text, watermark'],
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
pos: [473, 609],
|
||||
mode: 0,
|
||||
size: [315, 106],
|
||||
type: 'EmptyLatentImage',
|
||||
flags: {},
|
||||
order: 0,
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: 'LATENT',
|
||||
type: 'LATENT',
|
||||
links: [2],
|
||||
slot_index: 0,
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
'Node name for S&R': 'EmptyLatentImage',
|
||||
},
|
||||
widgets_values: [512, 512, 1],
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
pos: [1209, 188],
|
||||
mode: 0,
|
||||
size: [210, 46],
|
||||
type: 'VAEDecode',
|
||||
flags: {},
|
||||
order: 5,
|
||||
inputs: [
|
||||
{
|
||||
link: 7,
|
||||
name: 'samples',
|
||||
type: 'LATENT',
|
||||
},
|
||||
{
|
||||
link: 8,
|
||||
name: 'vae',
|
||||
type: 'VAE',
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'IMAGE',
|
||||
type: 'IMAGE',
|
||||
links: [9],
|
||||
slot_index: 0,
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
'Node name for S&R': 'VAEDecode',
|
||||
},
|
||||
widgets_values: [],
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
pos: [1451, 189],
|
||||
mode: 0,
|
||||
size: [210, 270],
|
||||
type: 'SaveImage',
|
||||
flags: {},
|
||||
order: 6,
|
||||
inputs: [
|
||||
{
|
||||
link: 9,
|
||||
name: 'images',
|
||||
type: 'IMAGE',
|
||||
},
|
||||
],
|
||||
outputs: [],
|
||||
properties: {
|
||||
'Node name for S&R': 'SaveImage',
|
||||
},
|
||||
widgets_values: ['ComfyUI'],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
pos: [],
|
||||
mode: 0,
|
||||
size: [315, 262],
|
||||
type: 'KSampler',
|
||||
flags: {},
|
||||
order: 4,
|
||||
inputs: [
|
||||
{
|
||||
link: 1,
|
||||
name: 'model',
|
||||
type: 'MODEL',
|
||||
},
|
||||
{
|
||||
link: 4,
|
||||
name: 'positive',
|
||||
type: 'CONDITIONING',
|
||||
},
|
||||
{
|
||||
link: 6,
|
||||
name: 'negative',
|
||||
type: 'CONDITIONING',
|
||||
},
|
||||
{
|
||||
link: 2,
|
||||
name: 'latent_image',
|
||||
type: 'LATENT',
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'LATENT',
|
||||
type: 'LATENT',
|
||||
links: [7],
|
||||
slot_index: 0,
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
'Node name for S&R': 'KSampler',
|
||||
},
|
||||
widgets_values: [
|
||||
253353381004563,
|
||||
'randomize',
|
||||
20,
|
||||
8,
|
||||
'euler',
|
||||
'normal',
|
||||
1,
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
pos: [],
|
||||
mode: 0,
|
||||
size: [315, 310],
|
||||
type: 'CheckpointLoaderSimple',
|
||||
flags: {},
|
||||
order: 1,
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: 'MODEL',
|
||||
type: 'MODEL',
|
||||
links: [1],
|
||||
slot_index: 0,
|
||||
},
|
||||
{
|
||||
name: 'CLIP',
|
||||
type: 'CLIP',
|
||||
links: [3, 5],
|
||||
slot_index: 1,
|
||||
},
|
||||
{
|
||||
name: 'VAE',
|
||||
type: 'VAE',
|
||||
links: [8],
|
||||
slot_index: 2,
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
'Node name for S&R': 'CheckpointLoaderSimple',
|
||||
},
|
||||
widgets_values: ['v1-5-pruned-emaonly-fp16.safetensors'],
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
pos: [415, 186],
|
||||
mode: 0,
|
||||
size: [422.8450317382812, 164.3130493164062],
|
||||
type: 'CLIPTextEncode',
|
||||
flags: {},
|
||||
order: 2,
|
||||
inputs: [
|
||||
{
|
||||
link: 3,
|
||||
name: 'clip',
|
||||
type: 'CLIP',
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'CONDITIONING',
|
||||
type: 'CONDITIONING',
|
||||
links: [4],
|
||||
slot_index: 0,
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
'Node name for S&R': 'CLIPTextEncode',
|
||||
},
|
||||
widgets_values: [
|
||||
'beautiful scenery nature glass bottle landscape, , purple galaxy bottle,',
|
||||
],
|
||||
},
|
||||
],
|
||||
config: {},
|
||||
groups: [],
|
||||
version: 0.4,
|
||||
last_link_id: 9,
|
||||
last_node_id: 9,
|
||||
},
|
||||
},
|
||||
},
|
||||
accelerator: 'L4',
|
||||
},
|
||||
workflow: null,
|
||||
workflow_api: null,
|
||||
workflow_id: 'xyz',
|
||||
output: [
|
||||
{
|
||||
filename:
|
||||
'/workflows/xyz/output/xyz/ComfyUI_00001_.png',
|
||||
url: 'https://r2.comfy.icu/workflows/xyz/output/CNCr5a_lu6g9Nz3gqKC9P/ComfyUI_00001_.png',
|
||||
thumbnail_url:
|
||||
'https://img.comfy.icu/sig/width:300/quality:85/xyz',
|
||||
},
|
||||
],
|
||||
error: null,
|
||||
files: {},
|
||||
name: null,
|
||||
tags: [],
|
||||
view_count: 0,
|
||||
download_count: 0,
|
||||
is_nsfw: false,
|
||||
user_id: '6VbYatQkJjualbDX84D2j',
|
||||
device: 'NVIDIA L4',
|
||||
accelerator: 'L4',
|
||||
visibility: 'PUBLIC',
|
||||
parent_workflow_id: null,
|
||||
parent_run_id: null,
|
||||
api_key_id: null,
|
||||
retry_count: 1,
|
||||
client_agent: null,
|
||||
webhook: null,
|
||||
project_id: 12297,
|
||||
user: {
|
||||
id: '6VbYatQkJjualbDX84D2j',
|
||||
name: 'John Doe',
|
||||
image: '',
|
||||
plan: 'FREE',
|
||||
},
|
||||
metadata: {
|
||||
extensions: ['comfyanonymous__ComfyUI'],
|
||||
nodes: [
|
||||
'CLIPTextEncode',
|
||||
'EmptyLatentImage',
|
||||
'VAEDecode',
|
||||
'SaveImage',
|
||||
'KSampler',
|
||||
'CheckpointLoaderSimple',
|
||||
],
|
||||
checkpoints: ['v1-5-pruned-emaonly-fp16.safetensors'],
|
||||
notes: [
|
||||
{
|
||||
text: 'text, watermark',
|
||||
},
|
||||
{
|
||||
text: 'beautiful scenery nature glass bottle landscape, , purple galaxy bottle,',
|
||||
},
|
||||
],
|
||||
groups: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,248 @@
|
||||
import { comfyIcuAuth } from '../../index';
|
||||
import {
|
||||
AppConnectionValueForAuthProperty,
|
||||
createTrigger,
|
||||
PiecePropValueSchema,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { comfyIcuApiCall, commonProps } from '../common';
|
||||
import {
|
||||
DedupeStrategy,
|
||||
HttpMethod,
|
||||
Polling,
|
||||
pollingHelper,
|
||||
} from '@activepieces/pieces-common';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const polling: Polling<
|
||||
AppConnectionValueForAuthProperty<typeof comfyIcuAuth>,
|
||||
{ workflow_id: string }
|
||||
> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
async items({ auth, propsValue, lastFetchEpochMS }) {
|
||||
const { workflow_id } = propsValue;
|
||||
const listRunsResponse = await comfyIcuApiCall({
|
||||
apiKey: auth,
|
||||
endpoint: `/workflows/${workflow_id}/runs`,
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
|
||||
const runs = listRunsResponse.body as {
|
||||
id: string;
|
||||
status: string;
|
||||
created_at: string;
|
||||
}[];
|
||||
|
||||
const result = [];
|
||||
|
||||
for (const run of runs) {
|
||||
if (run.status === 'ERROR') {
|
||||
const runDetailsResponse = await comfyIcuApiCall({
|
||||
apiKey: auth,
|
||||
endpoint: `/workflows/${workflow_id}/runs/${run.id}`,
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
const runDetail = runDetailsResponse.body as { created_at: string };
|
||||
result.push(runDetail);
|
||||
|
||||
if (lastFetchEpochMS === 0 && result.length === 5) break;
|
||||
}
|
||||
}
|
||||
|
||||
return result.map((run) => {
|
||||
return {
|
||||
epochMilliSeconds: dayjs(run.created_at).valueOf(),
|
||||
data: run,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const runFailedTrigger = createTrigger({
|
||||
auth: comfyIcuAuth,
|
||||
name: 'run-failed',
|
||||
displayName: 'Run Failed',
|
||||
description: 'Triggers when a workflow run is failed.',
|
||||
props: {
|
||||
workflow_id: commonProps.workflow_id,
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
sampleData: {
|
||||
id: 'sve-GBc89WPLPncm4laYG',
|
||||
created_at: '2025-05-23T15:09:44.273Z',
|
||||
updated_at: '2025-05-23T15:09:48.128Z',
|
||||
deleted_at: null,
|
||||
started_at: '2025-05-23T15:09:45.700Z',
|
||||
completed_at: '2025-05-23T15:09:47.997Z',
|
||||
run_time: 3,
|
||||
status: 'ERROR',
|
||||
kind: 'comfyui',
|
||||
data: {
|
||||
prompt: {
|
||||
'3': {
|
||||
_meta: {
|
||||
title: 'KSampler',
|
||||
},
|
||||
inputs: {
|
||||
cfg: 8,
|
||||
seed: 156680208700286,
|
||||
model: ['4', 0],
|
||||
steps: 20,
|
||||
denoise: 1,
|
||||
negative: ['7', 0],
|
||||
positive: ['6', 0],
|
||||
scheduler: 'normal',
|
||||
latent_image: ['5', 0],
|
||||
sampler_name: 'euler',
|
||||
},
|
||||
class_type: 'KSampler',
|
||||
},
|
||||
'4': {
|
||||
_meta: {
|
||||
title: 'Load Checkpoint',
|
||||
},
|
||||
inputs: {
|
||||
ckpt_name: 'v1-5-pruned-emaonly-fp16.safetensors',
|
||||
},
|
||||
class_type: 'CheckpointLoaderSimple',
|
||||
},
|
||||
'5': {
|
||||
_meta: {
|
||||
title: 'Empty Latent Image',
|
||||
},
|
||||
inputs: {
|
||||
width: 512,
|
||||
height: 512,
|
||||
batch_size: 1,
|
||||
},
|
||||
class_type: 'EmptyLatentImage',
|
||||
},
|
||||
'6': {
|
||||
_meta: {
|
||||
title: 'CLIP Text Encode (Prompt)',
|
||||
},
|
||||
inputs: {
|
||||
clip: ['4', 1],
|
||||
text: 'beautiful scenery nature glass bottle landscape, , purple galaxy bottle,',
|
||||
},
|
||||
class_type: 'CLIPTextEncode',
|
||||
},
|
||||
'7': {
|
||||
_meta: {
|
||||
title: 'CLIP Text Encode (Prompt)',
|
||||
},
|
||||
inputs: {
|
||||
clip: ['4', 1],
|
||||
text: 'text, watermark',
|
||||
},
|
||||
class_type: 'xx',
|
||||
},
|
||||
'8': {
|
||||
_meta: {
|
||||
title: 'VAE Decode',
|
||||
},
|
||||
inputs: {
|
||||
vae: ['4', 2],
|
||||
samples: ['3', 0],
|
||||
},
|
||||
class_type: 'VAEDecode',
|
||||
},
|
||||
'9': {
|
||||
_meta: {
|
||||
title: 'Save Image',
|
||||
},
|
||||
inputs: {
|
||||
images: ['8', 0],
|
||||
filename_prefix: 'ComfyUI',
|
||||
},
|
||||
class_type: 'SaveImage',
|
||||
},
|
||||
},
|
||||
webhook: '',
|
||||
},
|
||||
workflow: null,
|
||||
workflow_api: null,
|
||||
workflow_id: '46AnCzsekAoAXLZqVQUXH',
|
||||
output: {
|
||||
error: {
|
||||
details: {
|
||||
error: {
|
||||
type: 'invalid_prompt',
|
||||
details: "Node ID '#7'",
|
||||
message: 'Cannot execute because node xx does not exist.',
|
||||
extra_info: {},
|
||||
},
|
||||
node_errors: {},
|
||||
},
|
||||
prompt_id: 'sve-GBc89WPLPncm4laYG',
|
||||
traceback: [
|
||||
' File "/app/headless.py", line 771, in run_workflow\n prompt_id = self.queue_prompt(wf["prompt"])\n',
|
||||
' File "/app/headless.py", line 421, in queue_prompt\n raise RuntimeError(output)\n',
|
||||
],
|
||||
exception_type: 'invalid_prompt',
|
||||
exception_message:
|
||||
"Cannot execute because node xx does not exist.: Node ID '#7'",
|
||||
},
|
||||
output: {
|
||||
error: {
|
||||
details: {
|
||||
error: {
|
||||
type: 'invalid_prompt',
|
||||
details: "Node ID '#7'",
|
||||
message: 'Cannot execute because node xx does not exist.',
|
||||
extra_info: {},
|
||||
},
|
||||
node_errors: {},
|
||||
},
|
||||
prompt_id: 'sve-GBc89WPLPncm4laYG',
|
||||
traceback: [
|
||||
' File "/app/headless.py", line 771, in run_workflow\n prompt_id = self.queue_prompt(wf["prompt"])\n',
|
||||
' File "/app/headless.py", line 421, in queue_prompt\n raise RuntimeError(output)\n',
|
||||
],
|
||||
exception_type: 'invalid_prompt',
|
||||
exception_message:
|
||||
"Cannot execute because node xx does not exist.: Node ID '#7'",
|
||||
},
|
||||
},
|
||||
},
|
||||
error: null,
|
||||
files: {},
|
||||
name: null,
|
||||
tags: [],
|
||||
view_count: 0,
|
||||
download_count: 0,
|
||||
is_nsfw: false,
|
||||
user_id: '6VbYatQkJjualbDX84D2j',
|
||||
device: 'NVIDIA L4',
|
||||
accelerator: 'L4',
|
||||
visibility: 'PUBLIC',
|
||||
parent_workflow_id: null,
|
||||
parent_run_id: null,
|
||||
api_key_id: 'GM2FYwGmgiNpXTNDqT6MT',
|
||||
retry_count: 1,
|
||||
client_agent: null,
|
||||
webhook: '',
|
||||
project_id: 12297,
|
||||
user: null,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noPropertyAccessFromIndexSignature": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user