mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into simplify-docker-compose-setup
This commit is contained in:
commit
351078e8aa
6
.github/workflows/lint-frontend.yml
vendored
6
.github/workflows/lint-frontend.yml
vendored
@ -21,16 +21,16 @@ jobs:
|
|||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Node 20
|
- name: Setup Node 18
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '20'
|
node-version: '18'
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v2
|
uses: pnpm/action-setup@v2
|
||||||
with:
|
with:
|
||||||
version: 8
|
version: '8.12.1'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: 'pnpm install --prefer-frozen-lockfile'
|
run: 'pnpm install --prefer-frozen-lockfile'
|
||||||
- name: Typescript
|
- name: Typescript
|
||||||
|
50
.github/workflows/pypi-release.yml
vendored
50
.github/workflows/pypi-release.yml
vendored
@ -1,13 +1,15 @@
|
|||||||
name: PyPI Release
|
name: PyPI Release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'invokeai/version/invokeai_version.py'
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
publish_package:
|
||||||
|
description: 'Publish build on PyPi? [true/false]'
|
||||||
|
required: true
|
||||||
|
default: 'false'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
build-and-release:
|
||||||
if: github.repository == 'invoke-ai/InvokeAI'
|
if: github.repository == 'invoke-ai/InvokeAI'
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
env:
|
env:
|
||||||
@ -15,19 +17,43 @@ jobs:
|
|||||||
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
||||||
TWINE_NON_INTERACTIVE: 1
|
TWINE_NON_INTERACTIVE: 1
|
||||||
steps:
|
steps:
|
||||||
- name: checkout sources
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: install deps
|
- name: Setup Node 18
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '18'
|
||||||
|
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: '8.12.1'
|
||||||
|
|
||||||
|
- name: Install frontend dependencies
|
||||||
|
run: pnpm install --prefer-frozen-lockfile
|
||||||
|
working-directory: invokeai/frontend/web
|
||||||
|
|
||||||
|
- name: Build frontend
|
||||||
|
run: pnpm run build
|
||||||
|
working-directory: invokeai/frontend/web
|
||||||
|
|
||||||
|
- name: Install python dependencies
|
||||||
run: pip install --upgrade build twine
|
run: pip install --upgrade build twine
|
||||||
|
|
||||||
- name: build package
|
- name: Build python package
|
||||||
run: python3 -m build
|
run: python3 -m build
|
||||||
|
|
||||||
- name: check distribution
|
- name: Upload build as workflow artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: dist
|
||||||
|
path: dist
|
||||||
|
|
||||||
|
- name: Check distribution
|
||||||
run: twine check dist/*
|
run: twine check dist/*
|
||||||
|
|
||||||
- name: check PyPI versions
|
- name: Check PyPI versions
|
||||||
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')
|
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')
|
||||||
run: |
|
run: |
|
||||||
pip install --upgrade requests
|
pip install --upgrade requests
|
||||||
@ -36,6 +62,6 @@ jobs:
|
|||||||
EXISTS=scripts.pypi_helper.local_on_pypi(); \
|
EXISTS=scripts.pypi_helper.local_on_pypi(); \
|
||||||
print(f'PACKAGE_EXISTS={EXISTS}')" >> $GITHUB_ENV
|
print(f'PACKAGE_EXISTS={EXISTS}')" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: upload package
|
- name: Publish build on PyPi
|
||||||
if: env.PACKAGE_EXISTS == 'False' && env.TWINE_PASSWORD != ''
|
if: env.PACKAGE_EXISTS == 'False' && env.TWINE_PASSWORD != '' && github.event.inputs.publish_package == 'true'
|
||||||
run: twine upload dist/*
|
run: twine upload dist/*
|
||||||
|
10
docs/javascripts/init_kapa_widget.js
Normal file
10
docs/javascripts/init_kapa_widget.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
var script = document.createElement("script");
|
||||||
|
script.src = "https://widget.kapa.ai/kapa-widget.bundle.js";
|
||||||
|
script.setAttribute("data-website-id", "b5973bb1-476b-451e-8cf4-98de86745a10");
|
||||||
|
script.setAttribute("data-project-name", "Invoke.AI");
|
||||||
|
script.setAttribute("data-project-color", "#11213C");
|
||||||
|
script.setAttribute("data-project-logo", "https://avatars.githubusercontent.com/u/113954515?s=280&v=4");
|
||||||
|
script.async = true;
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
@ -91,9 +91,11 @@ rm -rf InvokeAI-Installer
|
|||||||
|
|
||||||
# copy content
|
# copy content
|
||||||
mkdir InvokeAI-Installer
|
mkdir InvokeAI-Installer
|
||||||
for f in templates lib *.txt *.reg; do
|
for f in templates *.txt *.reg; do
|
||||||
cp -r ${f} InvokeAI-Installer/
|
cp -r ${f} InvokeAI-Installer/
|
||||||
done
|
done
|
||||||
|
mkdir InvokeAI-Installer/lib
|
||||||
|
cp lib/*.py InvokeAI-Installer/lib
|
||||||
|
|
||||||
# Move the wheel
|
# Move the wheel
|
||||||
mv dist/*.whl InvokeAI-Installer/lib/
|
mv dist/*.whl InvokeAI-Installer/lib/
|
||||||
@ -111,6 +113,6 @@ cp WinLongPathsEnabled.reg InvokeAI-Installer/
|
|||||||
zip -r InvokeAI-installer-$VERSION.zip InvokeAI-Installer
|
zip -r InvokeAI-installer-$VERSION.zip InvokeAI-Installer
|
||||||
|
|
||||||
# clean up
|
# clean up
|
||||||
rm -rf InvokeAI-Installer tmp dist
|
rm -rf InvokeAI-Installer tmp dist ../invokeai/frontend/web/dist/
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -45,6 +45,9 @@ async def list_model_records(
|
|||||||
base_models: Optional[List[BaseModelType]] = Query(default=None, description="Base models to include"),
|
base_models: Optional[List[BaseModelType]] = Query(default=None, description="Base models to include"),
|
||||||
model_type: Optional[ModelType] = Query(default=None, description="The type of model to get"),
|
model_type: Optional[ModelType] = Query(default=None, description="The type of model to get"),
|
||||||
model_name: Optional[str] = Query(default=None, description="Exact match on the name of the model"),
|
model_name: Optional[str] = Query(default=None, description="Exact match on the name of the model"),
|
||||||
|
model_format: Optional[str] = Query(
|
||||||
|
default=None, description="Exact match on the format of the model (e.g. 'diffusers')"
|
||||||
|
),
|
||||||
) -> ModelsList:
|
) -> ModelsList:
|
||||||
"""Get a list of models."""
|
"""Get a list of models."""
|
||||||
record_store = ApiDependencies.invoker.services.model_records
|
record_store = ApiDependencies.invoker.services.model_records
|
||||||
@ -52,10 +55,14 @@ async def list_model_records(
|
|||||||
if base_models:
|
if base_models:
|
||||||
for base_model in base_models:
|
for base_model in base_models:
|
||||||
found_models.extend(
|
found_models.extend(
|
||||||
record_store.search_by_attr(base_model=base_model, model_type=model_type, model_name=model_name)
|
record_store.search_by_attr(
|
||||||
|
base_model=base_model, model_type=model_type, model_name=model_name, model_format=model_format
|
||||||
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
found_models.extend(record_store.search_by_attr(model_type=model_type, model_name=model_name))
|
found_models.extend(
|
||||||
|
record_store.search_by_attr(model_type=model_type, model_name=model_name, model_format=model_format)
|
||||||
|
)
|
||||||
return ModelsList(models=found_models)
|
return ModelsList(models=found_models)
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ from abc import ABC, abstractmethod
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
from invokeai.backend.model_manager.config import AnyModelConfig, BaseModelType, ModelType
|
from invokeai.backend.model_manager.config import AnyModelConfig, BaseModelType, ModelFormat, ModelType
|
||||||
|
|
||||||
|
|
||||||
class DuplicateModelException(Exception):
|
class DuplicateModelException(Exception):
|
||||||
@ -106,6 +106,7 @@ class ModelRecordServiceBase(ABC):
|
|||||||
model_name: Optional[str] = None,
|
model_name: Optional[str] = None,
|
||||||
base_model: Optional[BaseModelType] = None,
|
base_model: Optional[BaseModelType] = None,
|
||||||
model_type: Optional[ModelType] = None,
|
model_type: Optional[ModelType] = None,
|
||||||
|
model_format: Optional[ModelFormat] = None,
|
||||||
) -> List[AnyModelConfig]:
|
) -> List[AnyModelConfig]:
|
||||||
"""
|
"""
|
||||||
Return models matching name, base and/or type.
|
Return models matching name, base and/or type.
|
||||||
@ -113,6 +114,7 @@ class ModelRecordServiceBase(ABC):
|
|||||||
:param model_name: Filter by name of model (optional)
|
:param model_name: Filter by name of model (optional)
|
||||||
:param base_model: Filter by base model (optional)
|
:param base_model: Filter by base model (optional)
|
||||||
:param model_type: Filter by type of model (optional)
|
:param model_type: Filter by type of model (optional)
|
||||||
|
:param model_format: Filter by model format (e.g. "diffusers") (optional)
|
||||||
|
|
||||||
If none of the optional filters are passed, will return all
|
If none of the optional filters are passed, will return all
|
||||||
models in the database.
|
models in the database.
|
||||||
|
@ -49,6 +49,7 @@ from invokeai.backend.model_manager.config import (
|
|||||||
AnyModelConfig,
|
AnyModelConfig,
|
||||||
BaseModelType,
|
BaseModelType,
|
||||||
ModelConfigFactory,
|
ModelConfigFactory,
|
||||||
|
ModelFormat,
|
||||||
ModelType,
|
ModelType,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -225,6 +226,7 @@ class ModelRecordServiceSQL(ModelRecordServiceBase):
|
|||||||
model_name: Optional[str] = None,
|
model_name: Optional[str] = None,
|
||||||
base_model: Optional[BaseModelType] = None,
|
base_model: Optional[BaseModelType] = None,
|
||||||
model_type: Optional[ModelType] = None,
|
model_type: Optional[ModelType] = None,
|
||||||
|
model_format: Optional[ModelFormat] = None,
|
||||||
) -> List[AnyModelConfig]:
|
) -> List[AnyModelConfig]:
|
||||||
"""
|
"""
|
||||||
Return models matching name, base and/or type.
|
Return models matching name, base and/or type.
|
||||||
@ -232,6 +234,7 @@ class ModelRecordServiceSQL(ModelRecordServiceBase):
|
|||||||
:param model_name: Filter by name of model (optional)
|
:param model_name: Filter by name of model (optional)
|
||||||
:param base_model: Filter by base model (optional)
|
:param base_model: Filter by base model (optional)
|
||||||
:param model_type: Filter by type of model (optional)
|
:param model_type: Filter by type of model (optional)
|
||||||
|
:param model_format: Filter by model format (e.g. "diffusers") (optional)
|
||||||
|
|
||||||
If none of the optional filters are passed, will return all
|
If none of the optional filters are passed, will return all
|
||||||
models in the database.
|
models in the database.
|
||||||
@ -248,6 +251,9 @@ class ModelRecordServiceSQL(ModelRecordServiceBase):
|
|||||||
if model_type:
|
if model_type:
|
||||||
where_clause.append("type=?")
|
where_clause.append("type=?")
|
||||||
bindings.append(model_type)
|
bindings.append(model_type)
|
||||||
|
if model_format:
|
||||||
|
where_clause.append("format=?")
|
||||||
|
bindings.append(model_format)
|
||||||
where = f"WHERE {' AND '.join(where_clause)}" if where_clause else ""
|
where = f"WHERE {' AND '.join(where_clause)}" if where_clause else ""
|
||||||
with self._db.lock:
|
with self._db.lock:
|
||||||
self._cursor.execute(
|
self._cursor.execute(
|
||||||
|
@ -9,7 +9,7 @@ def lora_token_vector_length(checkpoint: dict) -> int:
|
|||||||
:param checkpoint: The checkpoint
|
:param checkpoint: The checkpoint
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _get_shape_1(key, tensor, checkpoint):
|
def _get_shape_1(key: str, tensor, checkpoint) -> int:
|
||||||
lora_token_vector_length = None
|
lora_token_vector_length = None
|
||||||
|
|
||||||
if "." not in key:
|
if "." not in key:
|
||||||
@ -57,6 +57,10 @@ def lora_token_vector_length(checkpoint: dict) -> int:
|
|||||||
for key, tensor in checkpoint.items():
|
for key, tensor in checkpoint.items():
|
||||||
if key.startswith("lora_unet_") and ("_attn2_to_k." in key or "_attn2_to_v." in key):
|
if key.startswith("lora_unet_") and ("_attn2_to_k." in key or "_attn2_to_v." in key):
|
||||||
lora_token_vector_length = _get_shape_1(key, tensor, checkpoint)
|
lora_token_vector_length = _get_shape_1(key, tensor, checkpoint)
|
||||||
|
elif key.startswith("lora_unet_") and (
|
||||||
|
"time_emb_proj.lora_down" in key
|
||||||
|
): # recognizes format at https://civitai.com/models/224641
|
||||||
|
lora_token_vector_length = _get_shape_1(key, tensor, checkpoint)
|
||||||
elif key.startswith("lora_te") and "_self_attn_" in key:
|
elif key.startswith("lora_te") and "_self_attn_" in key:
|
||||||
tmp_length = _get_shape_1(key, tensor, checkpoint)
|
tmp_length = _get_shape_1(key, tensor, checkpoint)
|
||||||
if key.startswith("lora_te_"):
|
if key.startswith("lora_te_"):
|
||||||
|
@ -400,6 +400,8 @@ class LoRACheckpointProbe(CheckpointProbeBase):
|
|||||||
return BaseModelType.StableDiffusion1
|
return BaseModelType.StableDiffusion1
|
||||||
elif token_vector_length == 1024:
|
elif token_vector_length == 1024:
|
||||||
return BaseModelType.StableDiffusion2
|
return BaseModelType.StableDiffusion2
|
||||||
|
elif token_vector_length == 1280:
|
||||||
|
return BaseModelType.StableDiffusionXL # recognizes format at https://civitai.com/models/224641
|
||||||
elif token_vector_length == 2048:
|
elif token_vector_length == 2048:
|
||||||
return BaseModelType.StableDiffusionXL
|
return BaseModelType.StableDiffusionXL
|
||||||
else:
|
else:
|
||||||
|
@ -950,9 +950,9 @@
|
|||||||
"problemSettingTitle": "Problem Setting Title",
|
"problemSettingTitle": "Problem Setting Title",
|
||||||
"reloadNodeTemplates": "Reload Node Templates",
|
"reloadNodeTemplates": "Reload Node Templates",
|
||||||
"removeLinearView": "Remove from Linear View",
|
"removeLinearView": "Remove from Linear View",
|
||||||
"resetWorkflow": "Reset Workflow Editor",
|
"newWorkflow": "New Workflow",
|
||||||
"resetWorkflowDesc": "Are you sure you want to reset the Workflow Editor?",
|
"newWorkflowDesc": "Create a new workflow?",
|
||||||
"resetWorkflowDesc2": "Resetting the Workflow Editor will clear all nodes, edges and workflow details. Saved workflows will not be affected.",
|
"newWorkflowDesc2": "Your current workflow has unsaved changes.",
|
||||||
"scheduler": "Scheduler",
|
"scheduler": "Scheduler",
|
||||||
"schedulerDescription": "TODO",
|
"schedulerDescription": "TODO",
|
||||||
"sDXLMainModelField": "SDXL Model",
|
"sDXLMainModelField": "SDXL Model",
|
||||||
@ -1634,10 +1634,10 @@
|
|||||||
"userWorkflows": "My Workflows",
|
"userWorkflows": "My Workflows",
|
||||||
"defaultWorkflows": "Default Workflows",
|
"defaultWorkflows": "Default Workflows",
|
||||||
"openWorkflow": "Open Workflow",
|
"openWorkflow": "Open Workflow",
|
||||||
"uploadWorkflow": "Upload Workflow",
|
"uploadWorkflow": "Load from File",
|
||||||
"deleteWorkflow": "Delete Workflow",
|
"deleteWorkflow": "Delete Workflow",
|
||||||
"unnamedWorkflow": "Unnamed Workflow",
|
"unnamedWorkflow": "Unnamed Workflow",
|
||||||
"downloadWorkflow": "Download Workflow",
|
"downloadWorkflow": "Save to File",
|
||||||
"saveWorkflow": "Save Workflow",
|
"saveWorkflow": "Save Workflow",
|
||||||
"saveWorkflowAs": "Save Workflow As",
|
"saveWorkflowAs": "Save Workflow As",
|
||||||
"savingWorkflow": "Saving Workflow...",
|
"savingWorkflow": "Saving Workflow...",
|
||||||
@ -1652,7 +1652,7 @@
|
|||||||
"searchWorkflows": "Search Workflows",
|
"searchWorkflows": "Search Workflows",
|
||||||
"clearWorkflowSearchFilter": "Clear Workflow Search Filter",
|
"clearWorkflowSearchFilter": "Clear Workflow Search Filter",
|
||||||
"workflowName": "Workflow Name",
|
"workflowName": "Workflow Name",
|
||||||
"workflowEditorReset": "Workflow Editor Reset",
|
"newWorkflowCreated": "New Workflow Created",
|
||||||
"workflowEditorMenu": "Workflow Editor Menu",
|
"workflowEditorMenu": "Workflow Editor Menu",
|
||||||
"workflowIsOpen": "Workflow is Open"
|
"workflowIsOpen": "Workflow is Open"
|
||||||
},
|
},
|
||||||
|
@ -727,9 +727,6 @@
|
|||||||
"showMinimapnodes": "Mostrar el minimapa",
|
"showMinimapnodes": "Mostrar el minimapa",
|
||||||
"reloadNodeTemplates": "Recargar las plantillas de nodos",
|
"reloadNodeTemplates": "Recargar las plantillas de nodos",
|
||||||
"loadWorkflow": "Cargar el flujo de trabajo",
|
"loadWorkflow": "Cargar el flujo de trabajo",
|
||||||
"resetWorkflow": "Reiniciar e flujo de trabajo",
|
|
||||||
"resetWorkflowDesc": "¿Está seguro de que deseas restablecer este flujo de trabajo?",
|
|
||||||
"resetWorkflowDesc2": "Al reiniciar el flujo de trabajo se borrarán todos los nodos, aristas y detalles del flujo de trabajo.",
|
|
||||||
"downloadWorkflow": "Descargar el flujo de trabajo en un archivo JSON"
|
"downloadWorkflow": "Descargar el flujo de trabajo en un archivo JSON"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -898,11 +898,8 @@
|
|||||||
"zoomInNodes": "Ingrandire",
|
"zoomInNodes": "Ingrandire",
|
||||||
"fitViewportNodes": "Adatta vista",
|
"fitViewportNodes": "Adatta vista",
|
||||||
"showGraphNodes": "Mostra sovrapposizione grafico",
|
"showGraphNodes": "Mostra sovrapposizione grafico",
|
||||||
"resetWorkflowDesc2": "Il ripristino dell'editor del flusso di lavoro cancellerà tutti i nodi, le connessioni e i dettagli del flusso di lavoro. I flussi di lavoro salvati non saranno interessati.",
|
|
||||||
"reloadNodeTemplates": "Ricarica i modelli di nodo",
|
"reloadNodeTemplates": "Ricarica i modelli di nodo",
|
||||||
"loadWorkflow": "Importa flusso di lavoro JSON",
|
"loadWorkflow": "Importa flusso di lavoro JSON",
|
||||||
"resetWorkflow": "Reimposta l'editor del flusso di lavoro",
|
|
||||||
"resetWorkflowDesc": "Sei sicuro di voler reimpostare l'editor del flusso di lavoro?",
|
|
||||||
"downloadWorkflow": "Esporta flusso di lavoro JSON",
|
"downloadWorkflow": "Esporta flusso di lavoro JSON",
|
||||||
"scheduler": "Campionatore",
|
"scheduler": "Campionatore",
|
||||||
"addNode": "Aggiungi nodo",
|
"addNode": "Aggiungi nodo",
|
||||||
@ -1619,7 +1616,6 @@
|
|||||||
"saveWorkflow": "Salva flusso di lavoro",
|
"saveWorkflow": "Salva flusso di lavoro",
|
||||||
"openWorkflow": "Apri flusso di lavoro",
|
"openWorkflow": "Apri flusso di lavoro",
|
||||||
"clearWorkflowSearchFilter": "Cancella il filtro di ricerca del flusso di lavoro",
|
"clearWorkflowSearchFilter": "Cancella il filtro di ricerca del flusso di lavoro",
|
||||||
"workflowEditorReset": "Reimpostazione dell'editor del flusso di lavoro",
|
|
||||||
"workflowLibrary": "Libreria",
|
"workflowLibrary": "Libreria",
|
||||||
"noRecentWorkflows": "Nessun flusso di lavoro recente",
|
"noRecentWorkflows": "Nessun flusso di lavoro recente",
|
||||||
"workflowSaved": "Flusso di lavoro salvato",
|
"workflowSaved": "Flusso di lavoro salvato",
|
||||||
|
@ -844,9 +844,6 @@
|
|||||||
"hideLegendNodes": "Typelegende veld verbergen",
|
"hideLegendNodes": "Typelegende veld verbergen",
|
||||||
"reloadNodeTemplates": "Herlaad knooppuntsjablonen",
|
"reloadNodeTemplates": "Herlaad knooppuntsjablonen",
|
||||||
"loadWorkflow": "Laad werkstroom",
|
"loadWorkflow": "Laad werkstroom",
|
||||||
"resetWorkflow": "Herstel werkstroom",
|
|
||||||
"resetWorkflowDesc": "Weet je zeker dat je deze werkstroom wilt herstellen?",
|
|
||||||
"resetWorkflowDesc2": "Herstel van een werkstroom haalt alle knooppunten, randen en werkstroomdetails weg.",
|
|
||||||
"downloadWorkflow": "Download JSON van werkstroom",
|
"downloadWorkflow": "Download JSON van werkstroom",
|
||||||
"booleanPolymorphicDescription": "Een verzameling Booleanse waarden.",
|
"booleanPolymorphicDescription": "Een verzameling Booleanse waarden.",
|
||||||
"scheduler": "Planner",
|
"scheduler": "Planner",
|
||||||
|
@ -909,9 +909,6 @@
|
|||||||
"hideLegendNodes": "Скрыть тип поля",
|
"hideLegendNodes": "Скрыть тип поля",
|
||||||
"showMinimapnodes": "Показать миникарту",
|
"showMinimapnodes": "Показать миникарту",
|
||||||
"loadWorkflow": "Загрузить рабочий процесс",
|
"loadWorkflow": "Загрузить рабочий процесс",
|
||||||
"resetWorkflowDesc2": "Сброс рабочего процесса очистит все узлы, ребра и детали рабочего процесса.",
|
|
||||||
"resetWorkflow": "Сбросить рабочий процесс",
|
|
||||||
"resetWorkflowDesc": "Вы уверены, что хотите сбросить этот рабочий процесс?",
|
|
||||||
"reloadNodeTemplates": "Перезагрузить шаблоны узлов",
|
"reloadNodeTemplates": "Перезагрузить шаблоны узлов",
|
||||||
"downloadWorkflow": "Скачать JSON рабочего процесса",
|
"downloadWorkflow": "Скачать JSON рабочего процесса",
|
||||||
"booleanPolymorphicDescription": "Коллекция логических значений.",
|
"booleanPolymorphicDescription": "Коллекция логических значений.",
|
||||||
@ -1599,7 +1596,6 @@
|
|||||||
"saveWorkflow": "Сохранить рабочий процесс",
|
"saveWorkflow": "Сохранить рабочий процесс",
|
||||||
"openWorkflow": "Открытый рабочий процесс",
|
"openWorkflow": "Открытый рабочий процесс",
|
||||||
"clearWorkflowSearchFilter": "Очистить фильтр поиска рабочих процессов",
|
"clearWorkflowSearchFilter": "Очистить фильтр поиска рабочих процессов",
|
||||||
"workflowEditorReset": "Сброс редактора рабочих процессов",
|
|
||||||
"workflowLibrary": "Библиотека",
|
"workflowLibrary": "Библиотека",
|
||||||
"downloadWorkflow": "Скачать рабочий процесс",
|
"downloadWorkflow": "Скачать рабочий процесс",
|
||||||
"noRecentWorkflows": "Нет недавних рабочих процессов",
|
"noRecentWorkflows": "Нет недавних рабочих процессов",
|
||||||
|
@ -892,11 +892,8 @@
|
|||||||
},
|
},
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"zoomInNodes": "放大",
|
"zoomInNodes": "放大",
|
||||||
"resetWorkflowDesc": "是否确定要重置工作流编辑器?",
|
|
||||||
"resetWorkflow": "重置工作流编辑器",
|
|
||||||
"loadWorkflow": "加载工作流",
|
"loadWorkflow": "加载工作流",
|
||||||
"zoomOutNodes": "缩小",
|
"zoomOutNodes": "缩小",
|
||||||
"resetWorkflowDesc2": "重置工作流编辑器将清除所有节点、边际和节点图详情。不影响已保存的工作流。",
|
|
||||||
"reloadNodeTemplates": "重载节点模板",
|
"reloadNodeTemplates": "重载节点模板",
|
||||||
"hideGraphNodes": "隐藏节点图信息",
|
"hideGraphNodes": "隐藏节点图信息",
|
||||||
"fitViewportNodes": "自适应视图",
|
"fitViewportNodes": "自适应视图",
|
||||||
@ -1637,7 +1634,6 @@
|
|||||||
"saveWorkflow": "保存工作流",
|
"saveWorkflow": "保存工作流",
|
||||||
"openWorkflow": "打开工作流",
|
"openWorkflow": "打开工作流",
|
||||||
"clearWorkflowSearchFilter": "清除工作流检索过滤器",
|
"clearWorkflowSearchFilter": "清除工作流检索过滤器",
|
||||||
"workflowEditorReset": "工作流编辑器重置",
|
|
||||||
"workflowLibrary": "工作流库",
|
"workflowLibrary": "工作流库",
|
||||||
"downloadWorkflow": "下载工作流",
|
"downloadWorkflow": "下载工作流",
|
||||||
"noRecentWorkflows": "无最近工作流",
|
"noRecentWorkflows": "无最近工作流",
|
||||||
|
@ -144,6 +144,7 @@ export const buildCanvasImageToImageGraph = (
|
|||||||
type: 'l2i',
|
type: 'l2i',
|
||||||
id: CANVAS_OUTPUT,
|
id: CANVAS_OUTPUT,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
|
use_cache: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edges: [
|
edges: [
|
||||||
@ -255,6 +256,7 @@ export const buildCanvasImageToImageGraph = (
|
|||||||
is_intermediate,
|
is_intermediate,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
|
use_cache: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
graph.edges.push(
|
graph.edges.push(
|
||||||
@ -295,6 +297,7 @@ export const buildCanvasImageToImageGraph = (
|
|||||||
id: CANVAS_OUTPUT,
|
id: CANVAS_OUTPUT,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
fp32,
|
fp32,
|
||||||
|
use_cache: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
(graph.nodes[IMAGE_TO_LATENTS] as ImageToLatentsInvocation).image =
|
(graph.nodes[IMAGE_TO_LATENTS] as ImageToLatentsInvocation).image =
|
||||||
|
@ -191,6 +191,7 @@ export const buildCanvasInpaintGraph = (
|
|||||||
id: CANVAS_OUTPUT,
|
id: CANVAS_OUTPUT,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
reference: canvasInitImage,
|
reference: canvasInitImage,
|
||||||
|
use_cache: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edges: [
|
edges: [
|
||||||
|
@ -199,6 +199,7 @@ export const buildCanvasOutpaintGraph = (
|
|||||||
type: 'color_correct',
|
type: 'color_correct',
|
||||||
id: CANVAS_OUTPUT,
|
id: CANVAS_OUTPUT,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
|
use_cache: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edges: [
|
edges: [
|
||||||
|
@ -266,6 +266,7 @@ export const buildCanvasSDXLImageToImageGraph = (
|
|||||||
is_intermediate,
|
is_intermediate,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
|
use_cache: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
graph.edges.push(
|
graph.edges.push(
|
||||||
@ -306,6 +307,7 @@ export const buildCanvasSDXLImageToImageGraph = (
|
|||||||
id: CANVAS_OUTPUT,
|
id: CANVAS_OUTPUT,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
fp32,
|
fp32,
|
||||||
|
use_cache: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
(graph.nodes[IMAGE_TO_LATENTS] as ImageToLatentsInvocation).image =
|
(graph.nodes[IMAGE_TO_LATENTS] as ImageToLatentsInvocation).image =
|
||||||
|
@ -196,6 +196,7 @@ export const buildCanvasSDXLInpaintGraph = (
|
|||||||
id: CANVAS_OUTPUT,
|
id: CANVAS_OUTPUT,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
reference: canvasInitImage,
|
reference: canvasInitImage,
|
||||||
|
use_cache: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edges: [
|
edges: [
|
||||||
|
@ -204,6 +204,7 @@ export const buildCanvasSDXLOutpaintGraph = (
|
|||||||
type: 'color_correct',
|
type: 'color_correct',
|
||||||
id: CANVAS_OUTPUT,
|
id: CANVAS_OUTPUT,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
|
use_cache: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edges: [
|
edges: [
|
||||||
|
@ -258,6 +258,7 @@ export const buildCanvasSDXLTextToImageGraph = (
|
|||||||
is_intermediate,
|
is_intermediate,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
|
use_cache: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
graph.edges.push(
|
graph.edges.push(
|
||||||
@ -288,6 +289,7 @@ export const buildCanvasSDXLTextToImageGraph = (
|
|||||||
id: CANVAS_OUTPUT,
|
id: CANVAS_OUTPUT,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
fp32,
|
fp32,
|
||||||
|
use_cache: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
graph.edges.push({
|
graph.edges.push({
|
||||||
|
@ -246,6 +246,7 @@ export const buildCanvasTextToImageGraph = (
|
|||||||
is_intermediate,
|
is_intermediate,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
|
use_cache: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
graph.edges.push(
|
graph.edges.push(
|
||||||
@ -276,6 +277,7 @@ export const buildCanvasTextToImageGraph = (
|
|||||||
id: CANVAS_OUTPUT,
|
id: CANVAS_OUTPUT,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
fp32,
|
fp32,
|
||||||
|
use_cache: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
graph.edges.push({
|
graph.edges.push({
|
||||||
|
@ -143,6 +143,7 @@ export const buildLinearImageToImageGraph = (
|
|||||||
// },
|
// },
|
||||||
fp32,
|
fp32,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
|
use_cache: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edges: [
|
edges: [
|
||||||
|
@ -154,6 +154,7 @@ export const buildLinearSDXLImageToImageGraph = (
|
|||||||
// },
|
// },
|
||||||
fp32,
|
fp32,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
|
use_cache: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edges: [
|
edges: [
|
||||||
|
@ -127,6 +127,7 @@ export const buildLinearSDXLTextToImageGraph = (
|
|||||||
id: LATENTS_TO_IMAGE,
|
id: LATENTS_TO_IMAGE,
|
||||||
fp32,
|
fp32,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
|
use_cache: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edges: [
|
edges: [
|
||||||
|
@ -146,6 +146,7 @@ export const buildLinearTextToImageGraph = (
|
|||||||
id: LATENTS_TO_IMAGE,
|
id: LATENTS_TO_IMAGE,
|
||||||
fp32,
|
fp32,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
|
use_cache: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edges: [
|
edges: [
|
||||||
|
@ -11,44 +11,48 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
|
import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { makeToast } from 'features/system/util/makeToast';
|
import { makeToast } from 'features/system/util/makeToast';
|
||||||
import { memo, useCallback, useRef } from 'react';
|
import { memo, useCallback, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaTrash } from 'react-icons/fa';
|
import { FaCircleNodes } from 'react-icons/fa6';
|
||||||
|
|
||||||
const ResetWorkflowEditorMenuItem = () => {
|
const NewWorkflowMenuItem = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const cancelRef = useRef<HTMLButtonElement | null>(null);
|
const cancelRef = useRef<HTMLButtonElement | null>(null);
|
||||||
|
const isTouched = useAppSelector((state) => state.workflow.isTouched);
|
||||||
|
|
||||||
const handleConfirmClear = useCallback(() => {
|
const handleNewWorkflow = useCallback(() => {
|
||||||
dispatch(nodeEditorReset());
|
dispatch(nodeEditorReset());
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
addToast(
|
addToast(
|
||||||
makeToast({
|
makeToast({
|
||||||
title: t('workflows.workflowEditorReset'),
|
title: t('workflows.newWorkflowCreated'),
|
||||||
status: 'success',
|
status: 'success',
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
onClose();
|
onClose();
|
||||||
}, [dispatch, t, onClose]);
|
}, [dispatch, onClose, t]);
|
||||||
|
|
||||||
|
const onClick = useCallback(() => {
|
||||||
|
if (!isTouched) {
|
||||||
|
handleNewWorkflow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onOpen();
|
||||||
|
}, [handleNewWorkflow, isTouched, onOpen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem as="button" icon={<FaCircleNodes />} onClick={onClick}>
|
||||||
as="button"
|
{t('nodes.newWorkflow')}
|
||||||
icon={<FaTrash />}
|
|
||||||
sx={{ color: 'error.600', _dark: { color: 'error.300' } }}
|
|
||||||
onClick={onOpen}
|
|
||||||
>
|
|
||||||
{t('nodes.resetWorkflow')}
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
<AlertDialog
|
<AlertDialog
|
||||||
@ -61,13 +65,13 @@ const ResetWorkflowEditorMenuItem = () => {
|
|||||||
|
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader fontSize="lg" fontWeight="bold">
|
<AlertDialogHeader fontSize="lg" fontWeight="bold">
|
||||||
{t('nodes.resetWorkflow')}
|
{t('nodes.newWorkflow')}
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
|
|
||||||
<AlertDialogBody py={4}>
|
<AlertDialogBody py={4}>
|
||||||
<Flex flexDir="column" gap={2}>
|
<Flex flexDir="column" gap={2}>
|
||||||
<Text>{t('nodes.resetWorkflowDesc')}</Text>
|
<Text>{t('nodes.newWorkflowDesc')}</Text>
|
||||||
<Text variant="subtext">{t('nodes.resetWorkflowDesc2')}</Text>
|
<Text variant="subtext">{t('nodes.newWorkflowDesc2')}</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</AlertDialogBody>
|
</AlertDialogBody>
|
||||||
|
|
||||||
@ -75,7 +79,7 @@ const ResetWorkflowEditorMenuItem = () => {
|
|||||||
<Button ref={cancelRef} onClick={onClose}>
|
<Button ref={cancelRef} onClick={onClose}>
|
||||||
{t('common.cancel')}
|
{t('common.cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button colorScheme="error" ml={3} onClick={handleConfirmClear}>
|
<Button colorScheme="error" ml={3} onClick={handleNewWorkflow}>
|
||||||
{t('common.accept')}
|
{t('common.accept')}
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
@ -85,4 +89,4 @@ const ResetWorkflowEditorMenuItem = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(ResetWorkflowEditorMenuItem);
|
export default memo(NewWorkflowMenuItem);
|
@ -9,7 +9,7 @@ import IAIIconButton from 'common/components/IAIIconButton';
|
|||||||
import { useGlobalMenuCloseTrigger } from 'common/hooks/useGlobalMenuCloseTrigger';
|
import { useGlobalMenuCloseTrigger } from 'common/hooks/useGlobalMenuCloseTrigger';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
import DownloadWorkflowMenuItem from 'features/workflowLibrary/components/WorkflowLibraryMenu/DownloadWorkflowMenuItem';
|
import DownloadWorkflowMenuItem from 'features/workflowLibrary/components/WorkflowLibraryMenu/DownloadWorkflowMenuItem';
|
||||||
import ResetWorkflowEditorMenuItem from 'features/workflowLibrary/components/WorkflowLibraryMenu/ResetWorkflowEditorMenuItem';
|
import NewWorkflowMenuItem from 'features/workflowLibrary/components/WorkflowLibraryMenu/NewWorkflowMenuItem';
|
||||||
import SaveWorkflowAsMenuItem from 'features/workflowLibrary/components/WorkflowLibraryMenu/SaveWorkflowAsMenuItem';
|
import SaveWorkflowAsMenuItem from 'features/workflowLibrary/components/WorkflowLibraryMenu/SaveWorkflowAsMenuItem';
|
||||||
import SaveWorkflowMenuItem from 'features/workflowLibrary/components/WorkflowLibraryMenu/SaveWorkflowMenuItem';
|
import SaveWorkflowMenuItem from 'features/workflowLibrary/components/WorkflowLibraryMenu/SaveWorkflowMenuItem';
|
||||||
import SettingsMenuItem from 'features/workflowLibrary/components/WorkflowLibraryMenu/SettingsMenuItem';
|
import SettingsMenuItem from 'features/workflowLibrary/components/WorkflowLibraryMenu/SettingsMenuItem';
|
||||||
@ -39,7 +39,7 @@ const WorkflowLibraryMenu = () => {
|
|||||||
{isWorkflowLibraryEnabled && <SaveWorkflowAsMenuItem />}
|
{isWorkflowLibraryEnabled && <SaveWorkflowAsMenuItem />}
|
||||||
<DownloadWorkflowMenuItem />
|
<DownloadWorkflowMenuItem />
|
||||||
<UploadWorkflowMenuItem />
|
<UploadWorkflowMenuItem />
|
||||||
<ResetWorkflowEditorMenuItem />
|
<NewWorkflowMenuItem />
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
<SettingsMenuItem />
|
<SettingsMenuItem />
|
||||||
</MenuList>
|
</MenuList>
|
||||||
|
@ -101,6 +101,8 @@ plugins:
|
|||||||
extra_javascript:
|
extra_javascript:
|
||||||
- https://unpkg.com/tablesort@5.3.0/dist/tablesort.min.js
|
- https://unpkg.com/tablesort@5.3.0/dist/tablesort.min.js
|
||||||
- javascripts/tablesort.js
|
- javascripts/tablesort.js
|
||||||
|
- https://widget.kapa.ai/kapa-widget.bundle.js
|
||||||
|
- javascript/init_kapa_widget.js
|
||||||
|
|
||||||
extra:
|
extra:
|
||||||
analytics:
|
analytics:
|
||||||
|
Loading…
Reference in New Issue
Block a user