mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-23 22:25:05 +00:00
Compare commits
9 Commits
ext-api/i-
...
glary/blue
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71ae5020bf | ||
|
|
f44f93907a | ||
|
|
ce1a44848d | ||
|
|
bb420fe2c7 | ||
|
|
4504256f11 | ||
|
|
1290bbd359 | ||
|
|
7ddf71d91b | ||
|
|
74caeb0b0b | ||
|
|
ced7c93e63 |
@@ -19,15 +19,26 @@ reviews:
|
||||
- name: End-to-end regression coverage for fixes
|
||||
mode: error
|
||||
instructions: |
|
||||
Use only PR metadata already available in the review context: the PR title, commit subjects in this PR, the files changed in this PR relative to the PR base (equivalent to `base...head`), and the PR description.
|
||||
Do not rely on shell commands. Do not inspect reverse diffs, files changed only on the base branch, or files outside this PR. If the changed-file list or commit subjects are unavailable, mark the check inconclusive instead of guessing.
|
||||
Use only PR metadata already available in the review context:
|
||||
- the PR title
|
||||
- commit subjects in this PR
|
||||
- The files changed in this PR relative to the PR base (equivalent to `base...head`)
|
||||
- the PR description.
|
||||
Do not rely on shell commands.
|
||||
Do not inspect reverse diffs, files changed only on the base branch, or files outside this PR.
|
||||
If the changed-file list or commit subjects are unavailable, mark the check inconclusive instead of guessing.
|
||||
|
||||
Pass if at least one of the following is true:
|
||||
1. Neither the PR title nor any commit subject in the PR uses bug-fix language such as `fix`, `fixed`, `fixes`, `fixing`, `bugfix`, or `hotfix`.
|
||||
2. The PR changes at least one file under `browser_tests/`.
|
||||
3. The PR description includes a concrete, non-placeholder explanation of why an end-to-end regression test was not added.
|
||||
Fail if all of the following are true:
|
||||
1. The PR title and/or any commit subject in the PR uses bug-fix language such as `fix`, `fixed`, `fixes`, `fixing`, `bugfix`, or `hotfix`.
|
||||
2. The PR changes files under `src/` or `packages/` related to the main frontend application but the PR does not change at least one file under `browser_tests/`.
|
||||
3. The PR description lacks a concrete explanation of why an end-to-end regression test was not added.
|
||||
|
||||
Do not fail if the changes are exclusively in `apps/website`, just documentation changes, or changes related to CI processes.
|
||||
The goal is to make sure that fixes include End-to-End regression tests. Do not insist on tests when the PR is not fixing a bug.
|
||||
|
||||
Pass otherwise.
|
||||
When failing, mention which bug-fix signal you found and ask the author to either add or update a Playwright regression test under `browser_tests/` or add a concrete explanation in the PR description of why an end-to-end regression test is not practical.
|
||||
|
||||
Fail otherwise. When failing, mention which bug-fix signal you found and ask the author to either add or update a Playwright regression test under `browser_tests/` or add a concrete explanation in the PR description of why an end-to-end regression test is not practical.
|
||||
- name: ADR compliance for entity/litegraph changes
|
||||
mode: warning
|
||||
instructions: |
|
||||
|
||||
@@ -26,7 +26,7 @@ const {
|
||||
<img
|
||||
src="/icons/node-left.svg"
|
||||
alt=""
|
||||
class="-mx-px self-stretch"
|
||||
class="-mx-px h-full w-auto self-stretch"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
@@ -38,7 +38,7 @@ const {
|
||||
v-if="i > 0"
|
||||
src="/icons/node-union.svg"
|
||||
alt=""
|
||||
class="-mx-px self-stretch"
|
||||
class="-mx-px h-full w-auto self-stretch"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<span
|
||||
@@ -72,7 +72,7 @@ const {
|
||||
<img
|
||||
src="/icons/node-right.svg"
|
||||
alt=""
|
||||
class="-mx-px self-stretch"
|
||||
class="-mx-px h-full w-auto self-stretch"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -470,6 +470,7 @@ const COLLECT_COVERAGE = process.env.COLLECT_COVERAGE === 'true'
|
||||
|
||||
export const comfyPageFixture = base.extend<{
|
||||
initialFeatureFlags: Record<string, unknown>
|
||||
initialSettings: Record<string, unknown>
|
||||
comfyPage: ComfyPage
|
||||
comfyMouse: ComfyMouse
|
||||
comfyFiles: ComfyFiles
|
||||
@@ -477,6 +478,10 @@ export const comfyPageFixture = base.extend<{
|
||||
// Allows configuring feature flags for tests with before initial setup:
|
||||
// `test.use({ initialFeatureFlags: { my_flag: true } })`.
|
||||
initialFeatureFlags: [{}, { option: true }],
|
||||
// Allows seeding user settings before initial page load:
|
||||
// `test.use({ initialSettings: { 'Comfy.Locale': 'zh' } })`. Merged on top of
|
||||
// the fixture's defaults so per-test values win.
|
||||
initialSettings: [{}, { option: true }],
|
||||
|
||||
page: async ({ page, browserName }, use) => {
|
||||
if (browserName !== 'chromium' || !COLLECT_COVERAGE) {
|
||||
@@ -494,7 +499,11 @@ export const comfyPageFixture = base.extend<{
|
||||
await mcr.add(coverage)
|
||||
},
|
||||
|
||||
comfyPage: async ({ page, request, initialFeatureFlags }, use, testInfo) => {
|
||||
comfyPage: async (
|
||||
{ page, request, initialFeatureFlags, initialSettings },
|
||||
use,
|
||||
testInfo
|
||||
) => {
|
||||
const comfyPage = new ComfyPage(page, request)
|
||||
|
||||
const { parallelIndex } = testInfo
|
||||
@@ -529,7 +538,8 @@ export const comfyPageFixture = base.extend<{
|
||||
// Disable errors tab to prevent missing model detection from
|
||||
// rendering error indicators on nodes during unrelated tests.
|
||||
'Comfy.RightSidePanel.ShowErrorsTab': false,
|
||||
...(isVueNodes && { 'Comfy.VueNodes.Enabled': true })
|
||||
...(isVueNodes && { 'Comfy.VueNodes.Enabled': true }),
|
||||
...initialSettings
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
|
||||
47
browser_tests/tests/customNodeLocales.spec.ts
Normal file
47
browser_tests/tests/customNodeLocales.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { CustomNodesI18n } from '@/schemas/apiSchema'
|
||||
import {
|
||||
comfyExpect as expect,
|
||||
comfyPageFixture as test
|
||||
} from '@e2e/fixtures/ComfyPage'
|
||||
|
||||
const NODE_TYPE = 'DevToolsNodeWithStringInput'
|
||||
const LOCALIZED_ZH = '本地化字符串输入 (ZH)'
|
||||
|
||||
const i18nResponse: CustomNodesI18n = {
|
||||
zh: {
|
||||
nodeDefs: {
|
||||
[NODE_TYPE]: { display_name: LOCALIZED_ZH }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test.describe(
|
||||
'Custom node locales loading',
|
||||
{ tag: ['@ui', '@vue-nodes'] },
|
||||
() => {
|
||||
test.use({ initialSettings: { 'Comfy.Locale': 'zh' } })
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.route('**/api/i18n', async (route) => {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(i18nResponse)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// Regression test for PR #7214 (issue #7025): custom-node i18n data was
|
||||
// clobbered when a non-English locale was lazily loaded, so nodes from
|
||||
// custom packs lost their translated display_name on locale switch.
|
||||
test('preserves custom-node /api/i18n translation through lazy locale load', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.nodeOps.addNode(NODE_TYPE)
|
||||
|
||||
await expect(comfyPage.vueNodes.getNodeByTitle(LOCALIZED_ZH)).toHaveCount(
|
||||
1
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@comfyorg/comfyui-frontend",
|
||||
"version": "1.45.4",
|
||||
"version": "1.45.5",
|
||||
"private": true,
|
||||
"description": "Official front-end implementation of ComfyUI",
|
||||
"homepage": "https://comfy.org",
|
||||
|
||||
@@ -146,6 +146,7 @@ import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
|
||||
import { useVueNodeLifecycle } from '@/composables/graph/useVueNodeLifecycle'
|
||||
import { useNodeBadge } from '@/composables/node/useNodeBadge'
|
||||
import { useCanvasDrop } from '@/composables/useCanvasDrop'
|
||||
import { useCanvasSearchBoxMenu } from '@/composables/useCanvasSearchBoxMenu'
|
||||
import { useContextMenuTranslation } from '@/composables/useContextMenuTranslation'
|
||||
import { useCopy } from '@/composables/useCopy'
|
||||
import { useGlobalLitegraph } from '@/composables/useGlobalLitegraph'
|
||||
@@ -459,6 +460,7 @@ useLitegraphSettings()
|
||||
useNodeBadge()
|
||||
|
||||
useGlobalLitegraph()
|
||||
useCanvasSearchBoxMenu()
|
||||
useContextMenuTranslation()
|
||||
useCopy()
|
||||
usePaste()
|
||||
|
||||
134
src/composables/useCanvasSearchBoxMenu.test.ts
Normal file
134
src/composables/useCanvasSearchBoxMenu.test.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { useCanvasSearchBoxMenu } from '@/composables/useCanvasSearchBoxMenu'
|
||||
import type {
|
||||
ContextMenu,
|
||||
IContextMenuValue
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphCanvas } from '@/lib/litegraph/src/litegraph'
|
||||
import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useSearchBoxStore } from '@/stores/workspace/searchBoxStore'
|
||||
import { createMockCanvas } from '@/utils/__tests__/litegraphTestUtils'
|
||||
|
||||
describe('useCanvasSearchBoxMenu', () => {
|
||||
let originalGetCanvasMenuOptions: typeof LGraphCanvas.prototype.getCanvasMenuOptions
|
||||
let mockCanvas: LGraphCanvas
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia())
|
||||
originalGetCanvasMenuOptions = LGraphCanvas.prototype.getCanvasMenuOptions
|
||||
|
||||
LGraphCanvas.prototype.getCanvasMenuOptions =
|
||||
function (): (IContextMenuValue | null)[] {
|
||||
const items: (IContextMenuValue<string> | null)[] = [
|
||||
{
|
||||
content: 'Add Node',
|
||||
has_submenu: true,
|
||||
callback: LGraphCanvas.onMenuAdd
|
||||
},
|
||||
{ content: 'Add Group', callback: vi.fn() }
|
||||
]
|
||||
return items as (IContextMenuValue | null)[]
|
||||
}
|
||||
|
||||
mockCanvas = createMockCanvas({
|
||||
constructor: { prototype: LGraphCanvas.prototype } as typeof LGraphCanvas
|
||||
} as Partial<LGraphCanvas>)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
LGraphCanvas.prototype.getCanvasMenuOptions = originalGetCanvasMenuOptions
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
function invokeAddNodeCallback(
|
||||
addNode: IContextMenuValue,
|
||||
previousMenu?: Partial<ContextMenu<unknown>>
|
||||
) {
|
||||
void addNode.callback?.call(
|
||||
addNode as never,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined as never,
|
||||
previousMenu as ContextMenu<unknown> | undefined
|
||||
)
|
||||
}
|
||||
|
||||
it('leaves the default Add Node entry untouched when the setting is off', () => {
|
||||
vi.spyOn(useSettingStore(), 'get').mockImplementation((id) =>
|
||||
id === 'Comfy.NodeSearchBox.ReplaceCanvasMenu' ? false : undefined
|
||||
)
|
||||
|
||||
useCanvasSearchBoxMenu()
|
||||
const items = LGraphCanvas.prototype.getCanvasMenuOptions.call(mockCanvas)
|
||||
|
||||
const addNode = items.find((i) => i?.content === 'Add Node')
|
||||
expect(addNode?.callback).toBe(LGraphCanvas.onMenuAdd)
|
||||
expect(addNode?.has_submenu).toBe(true)
|
||||
})
|
||||
|
||||
it('forwards the original right-click event to the search box so the node lands at the click position', () => {
|
||||
vi.spyOn(useSettingStore(), 'get').mockImplementation((id) =>
|
||||
id === 'Comfy.NodeSearchBox.ReplaceCanvasMenu' ? true : undefined
|
||||
)
|
||||
const openAtEvent = vi.spyOn(useSearchBoxStore(), 'openAtEvent')
|
||||
const toggleVisible = vi.spyOn(useSearchBoxStore(), 'toggleVisible')
|
||||
|
||||
const triggerEvent = {
|
||||
canvasX: 123,
|
||||
canvasY: 456
|
||||
} as unknown as CanvasPointerEvent
|
||||
const previousMenu = {
|
||||
getFirstEvent: () => triggerEvent
|
||||
} as unknown as Partial<ContextMenu<unknown>>
|
||||
|
||||
useCanvasSearchBoxMenu()
|
||||
const items = LGraphCanvas.prototype.getCanvasMenuOptions.call(mockCanvas)
|
||||
const addNode = items.find((i) => i?.content === 'Add Node')
|
||||
|
||||
expect(addNode).toBeTruthy()
|
||||
expect(addNode?.has_submenu).toBe(false)
|
||||
invokeAddNodeCallback(addNode!, previousMenu)
|
||||
|
||||
expect(openAtEvent).toHaveBeenCalledTimes(1)
|
||||
expect(openAtEvent).toHaveBeenCalledWith(triggerEvent)
|
||||
expect(toggleVisible).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('falls back to toggleVisible when no originating event is available', () => {
|
||||
vi.spyOn(useSettingStore(), 'get').mockReturnValue(true)
|
||||
const openAtEvent = vi.spyOn(useSearchBoxStore(), 'openAtEvent')
|
||||
const toggleVisible = vi.spyOn(useSearchBoxStore(), 'toggleVisible')
|
||||
|
||||
useCanvasSearchBoxMenu()
|
||||
const items = LGraphCanvas.prototype.getCanvasMenuOptions.call(mockCanvas)
|
||||
const addNode = items.find((i) => i?.content === 'Add Node')
|
||||
|
||||
invokeAddNodeCallback(addNode!, undefined)
|
||||
|
||||
expect(openAtEvent).not.toHaveBeenCalled()
|
||||
expect(toggleVisible).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('preserves other canvas menu entries', () => {
|
||||
vi.spyOn(useSettingStore(), 'get').mockReturnValue(true)
|
||||
|
||||
useCanvasSearchBoxMenu()
|
||||
const items = LGraphCanvas.prototype.getCanvasMenuOptions.call(mockCanvas)
|
||||
|
||||
const contents = items.map((i) => i?.content)
|
||||
expect(contents).toEqual(['Add Node', 'Add Group'])
|
||||
})
|
||||
|
||||
it('is idempotent across repeated invocations (HMR, remount)', () => {
|
||||
useCanvasSearchBoxMenu()
|
||||
const firstPatch = LGraphCanvas.prototype.getCanvasMenuOptions
|
||||
|
||||
useCanvasSearchBoxMenu()
|
||||
useCanvasSearchBoxMenu()
|
||||
|
||||
expect(LGraphCanvas.prototype.getCanvasMenuOptions).toBe(firstPatch)
|
||||
})
|
||||
})
|
||||
105
src/composables/useCanvasSearchBoxMenu.ts
Normal file
105
src/composables/useCanvasSearchBoxMenu.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { legacyMenuCompat } from '@/lib/litegraph/src/contextMenuCompat'
|
||||
import type {
|
||||
ContextMenu,
|
||||
IContextMenuValue
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphCanvas } from '@/lib/litegraph/src/litegraph'
|
||||
import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useSearchBoxStore } from '@/stores/workspace/searchBoxStore'
|
||||
|
||||
const REPLACE_SETTING_ID = 'Comfy.NodeSearchBox.ReplaceCanvasMenu'
|
||||
const WRAPPER_MARK = Symbol('useCanvasSearchBoxMenu.wrapper')
|
||||
|
||||
/**
|
||||
* When the experimental "replace canvas menu" setting is enabled, the
|
||||
* right-click canvas menu's "Add Node" entry opens the Vue node search box
|
||||
* (which already includes blueprints, partner nodes, core nodes, and
|
||||
* extensions) instead of the legacy LiteGraph category submenu.
|
||||
*
|
||||
* The replacement is identified by callback identity against
|
||||
* {@link LGraphCanvas.onMenuAdd} so it remains stable across the translation
|
||||
* wrapper installed by {@link useContextMenuTranslation}. The original
|
||||
* right-click event is forwarded via {@link ContextMenu.getFirstEvent} so the
|
||||
* resulting node lands at the click position instead of canvas center.
|
||||
*
|
||||
* Installation is idempotent: repeated calls (e.g. HMR remounts) do not stack
|
||||
* wrappers because the wrapper is tagged and detected on re-entry.
|
||||
*/
|
||||
export const useCanvasSearchBoxMenu = () => {
|
||||
legacyMenuCompat.install(LGraphCanvas.prototype, 'getCanvasMenuOptions')
|
||||
|
||||
const previousGetCanvasMenuOptions =
|
||||
LGraphCanvas.prototype.getCanvasMenuOptions
|
||||
if (isOurWrapper(previousGetCanvasMenuOptions)) return
|
||||
|
||||
const wrapped: typeof previousGetCanvasMenuOptions = function (
|
||||
this: LGraphCanvas,
|
||||
...args
|
||||
) {
|
||||
const items = previousGetCanvasMenuOptions.apply(this, args)
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
if (!settingStore.get(REPLACE_SETTING_ID)) return items
|
||||
|
||||
return items.map((item) =>
|
||||
isLegacyAddNode(item) ? buildSearchBoxAddNode(item) : item
|
||||
)
|
||||
}
|
||||
markAsOurWrapper(wrapped)
|
||||
|
||||
LGraphCanvas.prototype.getCanvasMenuOptions = wrapped
|
||||
legacyMenuCompat.registerWrapper(
|
||||
'getCanvasMenuOptions',
|
||||
wrapped,
|
||||
previousGetCanvasMenuOptions,
|
||||
LGraphCanvas.prototype
|
||||
)
|
||||
}
|
||||
|
||||
function isOurWrapper(fn: unknown): boolean {
|
||||
return !!fn && (fn as { [WRAPPER_MARK]?: true })[WRAPPER_MARK] === true
|
||||
}
|
||||
|
||||
function markAsOurWrapper(fn: object) {
|
||||
Object.defineProperty(fn, WRAPPER_MARK, {
|
||||
value: true,
|
||||
enumerable: false,
|
||||
configurable: false,
|
||||
writable: false
|
||||
})
|
||||
}
|
||||
|
||||
function isLegacyAddNode(
|
||||
item: IContextMenuValue | null
|
||||
): item is IContextMenuValue {
|
||||
return (
|
||||
!!item &&
|
||||
typeof item === 'object' &&
|
||||
item.callback === LGraphCanvas.onMenuAdd
|
||||
)
|
||||
}
|
||||
|
||||
function buildSearchBoxAddNode(original: IContextMenuValue): IContextMenuValue {
|
||||
return {
|
||||
...original,
|
||||
has_submenu: false,
|
||||
submenu: undefined,
|
||||
callback: (
|
||||
_value?: unknown,
|
||||
_options?: unknown,
|
||||
_event?: MouseEvent,
|
||||
previousMenu?: ContextMenu<unknown>
|
||||
) => {
|
||||
const triggerEvent = previousMenu?.getFirstEvent() as
|
||||
| CanvasPointerEvent
|
||||
| undefined
|
||||
const store = useSearchBoxStore()
|
||||
if (triggerEvent) {
|
||||
store.openAtEvent(triggerEvent)
|
||||
} else {
|
||||
store.toggleVisible()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "توليد موحد من النص إلى الصورة وتحرير دقيق لجملة واحدة بدقة تصل إلى 4K.",
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "التحكم بعد التوليد"
|
||||
},
|
||||
"model": {
|
||||
"name": "النموذج"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "فشل عند التوليد الجزئي"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "الارتفاع"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "أقصى عدد للصور"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "إعداد الحجم"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "العرض"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "الموجه",
|
||||
"tooltip": "موجه نصي لإنشاء أو تعديل صورة."
|
||||
},
|
||||
"seed": {
|
||||
"name": "البذرة",
|
||||
"tooltip": "البذرة المستخدمة للتوليد."
|
||||
},
|
||||
"watermark": {
|
||||
"name": "علامة مائية",
|
||||
"tooltip": "هل تريد إضافة علامة \"تم الإنشاء بواسطة الذكاء الاصطناعي\" على الصورة."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "توليد فيديو باستخدام نماذج ByteDance عبر API استنادًا إلى النص الموجه",
|
||||
"display_name": "ByteDance نص إلى فيديو",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "توليد الصور عبر Flux.2 [pro] أو Flux.2 [max] من موجه وصور مرجعية اختيارية.",
|
||||
"display_name": "Flux.2 Image",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "التحكم بعد التوليد"
|
||||
},
|
||||
"model": {
|
||||
"name": "النموذج"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "الارتفاع"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "العرض"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "الموجه",
|
||||
"tooltip": "موجه لتوليد أو تعديل الصورة"
|
||||
},
|
||||
"seed": {
|
||||
"name": "البذرة",
|
||||
"tooltip": "البذرة العشوائية المستخدمة لإنشاء الضوضاء."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "ينشئ الصور بشكل متزامن بناءً على النص والوَضوح.",
|
||||
"display_name": "Flux.2 [max] صورة",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "تعديل صورة موجودة بناءً على موجه نصي",
|
||||
"display_name": "تعديل صورة Grok",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "التحكم بعد التوليد"
|
||||
},
|
||||
"model": {
|
||||
"name": "النموذج"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "نسبة العرض إلى الارتفاع"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "عدد الصور"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "الدقة"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "الموجه",
|
||||
"tooltip": "الموجه النصي المستخدم لتوليد الصورة"
|
||||
},
|
||||
"seed": {
|
||||
"name": "البذرة",
|
||||
"tooltip": "البذرة لتحديد ما إذا كان يجب إعادة تشغيل العقدة؛ النتائج الفعلية غير حتمية بغض النظر عن البذرة."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "توليد صور باستخدام Grok بناءً على مطالبة نصية",
|
||||
"display_name": "صورة Grok",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "توليد الصور عبر نقطة نهاية GPT Image من OpenAI.",
|
||||
"display_name": "OpenAI GPT Image 2",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "التحكم بعد التوليد"
|
||||
},
|
||||
"model": {
|
||||
"name": "النموذج"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "الخلفية"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "ارتفاع مخصص"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "عرض مخصص"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "الجودة"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "الحجم"
|
||||
},
|
||||
"n": {
|
||||
"name": "عدد الصور",
|
||||
"tooltip": "كم عدد الصور التي سيتم توليدها"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "الموجه",
|
||||
"tooltip": "موجه نصي لـ GPT Image"
|
||||
},
|
||||
"seed": {
|
||||
"name": "البذرة",
|
||||
"tooltip": "لم يتم تطبيقها بعد في الخلفية"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "يقوم بتحميل وإعداد ملفات الإدخال (نص، pdf، إلخ) لتضمينها كمدخلات لعقدة OpenAI Chat. سيتم قراءة الملفات بواسطة نموذج OpenAI عند إنشاء الرد. 🛈 تلميح: يمكن ربطها مع عقد OpenAI Input File الأخرى.",
|
||||
"display_name": "OpenAI ChatGPT Input Files",
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"description": "Unified text-to-image generation and precise single-sentence editing at up to 4K resolution.",
|
||||
"inputs": {
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Text prompt for creating or editing an image."
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "Seed to use for generation."
|
||||
},
|
||||
"watermark": {
|
||||
"name": "watermark",
|
||||
"tooltip": "Whether to add an \"AI generated\" watermark to the image."
|
||||
},
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "fail_on_partial"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "height"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "max_images"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "size_preset"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "width"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"display_name": "ByteDance Text to Video",
|
||||
"description": "Generate video using ByteDance models via api based on prompt",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"display_name": "Flux.2 Image",
|
||||
"description": "Generate images via Flux.2 [pro] or Flux.2 [max] from a prompt and optional reference images.",
|
||||
"inputs": {
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Prompt for the image generation or edit"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "The random seed used for creating the noise."
|
||||
},
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "height"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "width"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"display_name": "Flux.2 [max] Image",
|
||||
"description": "Generates images synchronously based on prompt and resolution.",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"display_name": "Grok Image Edit",
|
||||
"description": "Modify an existing image based on a text prompt",
|
||||
"inputs": {
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "The text prompt used to generate the image"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "Seed to determine if node should re-run; actual results are nondeterministic regardless of seed."
|
||||
},
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "aspect_ratio"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "number_of_images"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "resolution"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"display_name": "Grok Image",
|
||||
"description": "Generate images using Grok based on a text prompt",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"display_name": "OpenAI GPT Image 2",
|
||||
"description": "Generates images via OpenAI's GPT Image endpoint.",
|
||||
"inputs": {
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Text prompt for GPT Image"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"n": {
|
||||
"name": "n",
|
||||
"tooltip": "How many images to generate"
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "not implemented yet in backend"
|
||||
},
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "background"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "custom_height"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "custom_width"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "quality"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "size"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"display_name": "OpenAI ChatGPT Input Files",
|
||||
"description": "Loads and prepares input files (text, pdf, etc.) to include as inputs for the OpenAI Chat Node. The files will be read by the OpenAI model when generating a response. 🛈 TIP: Can be chained together with other OpenAI Input File nodes.",
|
||||
|
||||
@@ -328,6 +328,10 @@
|
||||
"name": "Show node frequency in search results",
|
||||
"tooltip": "Only applies to v1 (legacy)"
|
||||
},
|
||||
"Comfy_NodeSearchBox_ReplaceCanvasMenu": {
|
||||
"name": "Replace canvas right-click \"Add Node\" with search box",
|
||||
"tooltip": "When enabled, the right-click canvas menu opens the node search box instead of the LiteGraph category submenu. The search box includes blueprints, partner nodes, core nodes, and extensions."
|
||||
},
|
||||
"Comfy_NodeSuggestions_number": {
|
||||
"name": "Number of nodes suggestions",
|
||||
"tooltip": "Only for litegraph searchbox/context menu"
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "Generación unificada de texto a imagen y edición precisa de una sola frase hasta una resolución de 4K.",
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control después de generar"
|
||||
},
|
||||
"model": {
|
||||
"name": "modelo"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "fallar_en_parcial"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "altura"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "imágenes_máximas"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "preajuste_de_tamaño"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "ancho"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Indicador de texto para crear o editar una imagen."
|
||||
},
|
||||
"seed": {
|
||||
"name": "semilla",
|
||||
"tooltip": "Semilla a utilizar para la generación."
|
||||
},
|
||||
"watermark": {
|
||||
"name": "marca de agua",
|
||||
"tooltip": "Indica si se añade una marca de agua de \"Generado por IA\" a la imagen."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "Generar video usando modelos de ByteDance mediante API basado en prompt",
|
||||
"display_name": "ByteDance Texto a Video",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "Genera imágenes mediante Flux.2 [pro] o Flux.2 [max] a partir de un prompt y, opcionalmente, imágenes de referencia.",
|
||||
"display_name": "Flux.2 Image",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control después de generar"
|
||||
},
|
||||
"model": {
|
||||
"name": "modelo"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "altura"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "ancho"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Prompt para la generación o edición de la imagen"
|
||||
},
|
||||
"seed": {
|
||||
"name": "semilla",
|
||||
"tooltip": "La semilla aleatoria utilizada para crear el ruido."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "Genera imágenes de forma sincrónica según el prompt y la resolución.",
|
||||
"display_name": "Flux.2 [max] Imagen",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "Modifica una imagen existente en base a un prompt de texto",
|
||||
"display_name": "Grok Image Edit",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control después de generar"
|
||||
},
|
||||
"model": {
|
||||
"name": "modelo"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "relación_de_aspecto"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "número_de_imágenes"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "resolución"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "El prompt de texto utilizado para generar la imagen"
|
||||
},
|
||||
"seed": {
|
||||
"name": "semilla",
|
||||
"tooltip": "Semilla para determinar si el nodo debe volver a ejecutarse; los resultados reales son no deterministas independientemente de la semilla."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "Genera imágenes usando Grok a partir de una indicación de texto",
|
||||
"display_name": "Imagen Grok",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "Genera imágenes a través del endpoint GPT Image de OpenAI.",
|
||||
"display_name": "OpenAI GPT Image 2",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control después de generar"
|
||||
},
|
||||
"model": {
|
||||
"name": "modelo"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "fondo"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "altura_personalizada"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "ancho_personalizado"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "calidad"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "tamaño"
|
||||
},
|
||||
"n": {
|
||||
"name": "n",
|
||||
"tooltip": "Cuántas imágenes generar"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Prompt de texto para GPT Image"
|
||||
},
|
||||
"seed": {
|
||||
"name": "semilla",
|
||||
"tooltip": "aún no implementado en el backend"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "Carga y prepara archivos de entrada (texto, pdf, etc.) para incluirlos como entradas para el Nodo de Chat de OpenAI. Los archivos serán leídos por el modelo de OpenAI al generar una respuesta. 🛈 CONSEJO: Se puede encadenar con otros nodos de Archivos de Entrada de OpenAI.",
|
||||
"display_name": "Archivos de Entrada de OpenAI ChatGPT",
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "تولید تصویر از متن و ویرایش دقیق جملهای با وضوح تا ۴K به صورت یکپارچه.",
|
||||
"display_name": "ByteDance Seedream ۴.۵ و ۵.۰",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "fail_on_partial"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "height"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "max_images"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "size_preset"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "width"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "پرامپت متنی برای ایجاد یا ویرایش تصویر."
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "Seed مورد استفاده برای تولید."
|
||||
},
|
||||
"watermark": {
|
||||
"name": "watermark",
|
||||
"tooltip": "آیا واترمارک «تولید شده توسط هوش مصنوعی» به تصویر اضافه شود یا خیر."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "تولید ویدیو با استفاده از مدلهای ByteDance از طریق API بر اساس پرامپت",
|
||||
"display_name": "تبدیل متن به ویدیو ByteDance",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "تولید تصویر با استفاده از Flux.2 [pro] یا Flux.2 [max] از طریق پرامپت و تصاویر مرجع اختیاری.",
|
||||
"display_name": "Flux.2 Image",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "height"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "width"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "پرامپت برای تولید یا ویرایش تصویر"
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "Seed تصادفی برای ایجاد نویز."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "تولید تصویر به صورت همزمان بر اساس پرامپت و وضوح تصویر.",
|
||||
"display_name": "Flux.2 [max] Image",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "ویرایش یک تصویر موجود بر اساس پرامپت متنی",
|
||||
"display_name": "Grok Image Edit",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "aspect_ratio"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "number_of_images"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "resolution"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "پرامپت متنی برای تولید تصویر"
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "Seed برای تعیین اجرای مجدد node؛ نتایج واقعی صرفنظر از seed غیرقطعی هستند."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "تولید تصویر با استفاده از Grok بر اساس یک متن راهنما",
|
||||
"display_name": "تصویر Grok",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "تولید تصویر از طریق سرویس GPT Image شرکت OpenAI.",
|
||||
"display_name": "OpenAI GPT Image ۲",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "background"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "custom_height"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "custom_width"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "quality"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "size"
|
||||
},
|
||||
"n": {
|
||||
"name": "n",
|
||||
"tooltip": "تعداد تصاویری که باید تولید شود"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "پرامپت متنی برای GPT Image"
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "در backend هنوز پیادهسازی نشده است"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "بارگذاری و آمادهسازی فایلهای ورودی (متن، PDF و غیره) برای استفاده به عنوان ورودی در Node چت OpenAI. این فایلها هنگام تولید پاسخ توسط مدل OpenAI خوانده میشوند. 🛈 نکته: میتوان این node را با سایر nodeهای فایل ورودی OpenAI زنجیره کرد.",
|
||||
"display_name": "فایلهای ورودی OpenAI ChatGPT",
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "Génération d'image à partir de texte unifiée et édition précise d'une seule phrase jusqu'à une résolution 4K.",
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "contrôle après génération"
|
||||
},
|
||||
"model": {
|
||||
"name": "modèle"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "échec_sur_partiel"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "hauteur"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "images_max"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "préréglage_taille"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "largeur"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Invite textuelle pour créer ou éditer une image."
|
||||
},
|
||||
"seed": {
|
||||
"name": "graine",
|
||||
"tooltip": "Graine à utiliser pour la génération."
|
||||
},
|
||||
"watermark": {
|
||||
"name": "filigrane",
|
||||
"tooltip": "Ajouter ou non un filigrane « Généré par IA » à l’image."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "Générer une vidéo en utilisant les modèles ByteDance via l'API basée sur l'invite",
|
||||
"display_name": "ByteDance Texte vers Vidéo",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "Générez des images via Flux.2 [pro] ou Flux.2 [max] à partir d’un prompt et d’images de référence optionnelles.",
|
||||
"display_name": "Flux.2 Image",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "contrôle après génération"
|
||||
},
|
||||
"model": {
|
||||
"name": "modèle"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "hauteur"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "largeur"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Prompt pour la génération ou l’édition d’image"
|
||||
},
|
||||
"seed": {
|
||||
"name": "graine",
|
||||
"tooltip": "La graine aléatoire utilisée pour créer le bruit."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "Génère des images de manière synchrone à partir d'une invite et d'une résolution.",
|
||||
"display_name": "Flux.2 [max] Image",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "Modifiez une image existante à partir d’un prompt textuel",
|
||||
"display_name": "Grok Image Edit",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "contrôle après génération"
|
||||
},
|
||||
"model": {
|
||||
"name": "modèle"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "ratio_d’aspect"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "nombre_d’images"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "résolution"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Le prompt textuel utilisé pour générer l’image"
|
||||
},
|
||||
"seed": {
|
||||
"name": "graine",
|
||||
"tooltip": "Graine pour déterminer si le nœud doit être relancé ; les résultats réels sont non déterministes quel que soit la graine."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "Générez des images avec Grok à partir d'une invite textuelle",
|
||||
"display_name": "Grok Image",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "Génère des images via l’API GPT Image d’OpenAI.",
|
||||
"display_name": "OpenAI GPT Image 2",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "contrôle après génération"
|
||||
},
|
||||
"model": {
|
||||
"name": "modèle"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "arrière-plan"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "hauteur_personnalisée"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "largeur_personnalisée"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "qualité"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "taille"
|
||||
},
|
||||
"n": {
|
||||
"name": "n",
|
||||
"tooltip": "Combien d’images générer"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Prompt textuel pour GPT Image"
|
||||
},
|
||||
"seed": {
|
||||
"name": "graine",
|
||||
"tooltip": "non implémenté côté serveur pour le moment"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "Charge et prépare les fichiers d'entrée (texte, pdf, etc.) à inclure comme entrées pour le nœud de chat OpenAI. Les fichiers seront lus par le modèle OpenAI lors de la génération d'une réponse. 🛈 ASTUCE : Peut être chaîné avec d'autres nœuds de fichiers d'entrée OpenAI.",
|
||||
"display_name": "Fichiers d'entrée OpenAI ChatGPT",
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "統合されたテキストから画像生成と、最大4K解像度での正確な単一文編集。",
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成後のコントロール"
|
||||
},
|
||||
"model": {
|
||||
"name": "モデル"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "部分的な失敗時に停止"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "高さ"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "最大画像数"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "サイズプリセット"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "幅"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "プロンプト",
|
||||
"tooltip": "画像の作成または編集のためのテキストプロンプト。"
|
||||
},
|
||||
"seed": {
|
||||
"name": "シード",
|
||||
"tooltip": "生成に使用するシード。"
|
||||
},
|
||||
"watermark": {
|
||||
"name": "ウォーターマーク",
|
||||
"tooltip": "画像に「AI生成」のウォーターマークを追加するかどうか。"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "プロンプトに基づきAPI経由でByteDanceモデルを使用して動画を生成",
|
||||
"display_name": "ByteDance テキストから動画へ",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "Flux.2 [pro] または Flux.2 [max] を使い、プロンプトとオプションの参照画像から画像を生成します。",
|
||||
"display_name": "Flux.2 Image",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成後のコントロール"
|
||||
},
|
||||
"model": {
|
||||
"name": "モデル"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "高さ"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "幅"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "プロンプト",
|
||||
"tooltip": "画像生成または編集のためのプロンプト"
|
||||
},
|
||||
"seed": {
|
||||
"name": "シード",
|
||||
"tooltip": "ノイズ生成に使用されるランダムシード。"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "プロンプトと解像度に基づいて同期的に画像を生成します。",
|
||||
"display_name": "Flux.2 [max] 画像",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "既存の画像をテキストプロンプトに基づいて編集します",
|
||||
"display_name": "Grok Image Edit",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成後のコントロール"
|
||||
},
|
||||
"model": {
|
||||
"name": "モデル"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "アスペクト比"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "画像数"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "解像度"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "プロンプト",
|
||||
"tooltip": "画像生成に使用されるテキストプロンプト"
|
||||
},
|
||||
"seed": {
|
||||
"name": "シード",
|
||||
"tooltip": "ノードを再実行するかどうかを決定するシード;実際の結果はシードに関係なく非決定的です。"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "テキストプロンプトに基づいてGrokで画像を生成します",
|
||||
"display_name": "Grok画像生成",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "OpenAIのGPT Imageエンドポイントを使って画像を生成します。",
|
||||
"display_name": "OpenAI GPT Image 2",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成後のコントロール"
|
||||
},
|
||||
"model": {
|
||||
"name": "モデル"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "背景"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "カスタム高さ"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "カスタム幅"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "品質"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "サイズ"
|
||||
},
|
||||
"n": {
|
||||
"name": "n",
|
||||
"tooltip": "生成する画像の数"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "プロンプト",
|
||||
"tooltip": "GPT Image用のテキストプロンプト"
|
||||
},
|
||||
"seed": {
|
||||
"name": "シード",
|
||||
"tooltip": "バックエンドではまだ未実装"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "OpenAIチャットノードの入力として含める入力ファイル(テキスト、PDFなど)を読み込み、準備します。ファイルはOpenAIモデルによって応答生成時に読み込まれます。🛈 ヒント: 他のOpenAI入力ファイルノードと連結できます。",
|
||||
"display_name": "OpenAI ChatGPT 入力ファイル",
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "최대 4K 해상도에서 통합 텍스트-이미지 생성 및 정밀한 단일 문장 편집.",
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "생성 후 제어"
|
||||
},
|
||||
"model": {
|
||||
"name": "모델"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "부분 실패 시 중단"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "높이"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "최대 이미지 수"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "사이즈 프리셋"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "너비"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "프롬프트",
|
||||
"tooltip": "이미지를 생성하거나 편집하기 위한 텍스트 프롬프트입니다."
|
||||
},
|
||||
"seed": {
|
||||
"name": "시드",
|
||||
"tooltip": "생성에 사용할 시드입니다."
|
||||
},
|
||||
"watermark": {
|
||||
"name": "워터마크",
|
||||
"tooltip": "이미지에 \"AI 생성됨\" 워터마크를 추가할지 여부입니다."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "프롬프트를 기반으로 API를 통해 ByteDance 모델을 사용하여 비디오 생성",
|
||||
"display_name": "ByteDance 텍스트-비디오",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "프롬프트와 선택적 참조 이미지를 통해 Flux.2 [pro] 또는 Flux.2 [max]로 이미지 생성.",
|
||||
"display_name": "Flux.2 Image",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "생성 후 제어"
|
||||
},
|
||||
"model": {
|
||||
"name": "모델"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "높이"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "너비"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "프롬프트",
|
||||
"tooltip": "이미지 생성 또는 편집을 위한 프롬프트"
|
||||
},
|
||||
"seed": {
|
||||
"name": "시드",
|
||||
"tooltip": "노이즈 생성을 위한 랜덤 시드입니다."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "프롬프트와 해상도에 따라 이미지를 동기적으로 생성합니다.",
|
||||
"display_name": "Flux.2 [max] 이미지",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "텍스트 프롬프트를 기반으로 기존 이미지를 수정합니다.",
|
||||
"display_name": "Grok 이미지 편집",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "생성 후 제어"
|
||||
},
|
||||
"model": {
|
||||
"name": "모델"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "종횡비"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "이미지 개수"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "해상도"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "프롬프트",
|
||||
"tooltip": "이미지 생성을 위해 사용되는 텍스트 프롬프트입니다."
|
||||
},
|
||||
"seed": {
|
||||
"name": "시드",
|
||||
"tooltip": "노드가 다시 실행되어야 하는지 결정하는 시드입니다. 실제 결과는 시드와 관계없이 비결정적입니다."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "텍스트 프롬프트를 기반으로 Grok을 사용해 이미지를 생성합니다",
|
||||
"display_name": "Grok 이미지",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "OpenAI의 GPT 이미지 엔드포인트를 통해 이미지를 생성합니다.",
|
||||
"display_name": "OpenAI GPT 이미지 2",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "생성 후 제어"
|
||||
},
|
||||
"model": {
|
||||
"name": "모델"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "배경"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "사용자 지정 높이"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "사용자 지정 너비"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "품질"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "사이즈"
|
||||
},
|
||||
"n": {
|
||||
"name": "개수",
|
||||
"tooltip": "생성할 이미지 수"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "프롬프트",
|
||||
"tooltip": "GPT 이미지용 텍스트 프롬프트"
|
||||
},
|
||||
"seed": {
|
||||
"name": "시드",
|
||||
"tooltip": "백엔드에서 아직 구현되지 않음"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "OpenAI 채팅 노드에 대한 입력으로 포함할 입력 파일(텍스트, PDF 등)을 로드하고 준비합니다. 파일은 OpenAI 모델이 응답을 생성할 때 읽힙니다. 🛈 팁: 다른 OpenAI 입력 파일 노드와 함께 연결하여 사용할 수 있습니다.",
|
||||
"display_name": "OpenAI ChatGPT 입력 파일",
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "Geração unificada de texto para imagem e edição precisa de frases únicas em até 4K de resolução.",
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "controle após gerar"
|
||||
},
|
||||
"model": {
|
||||
"name": "modelo"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "falhar_em_parcial"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "altura"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "máx_imagens"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "predefinição_de_tamanho"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "largura"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Prompt de texto para criar ou editar uma imagem."
|
||||
},
|
||||
"seed": {
|
||||
"name": "semente",
|
||||
"tooltip": "Semente utilizada para a geração."
|
||||
},
|
||||
"watermark": {
|
||||
"name": "marca d'água",
|
||||
"tooltip": "Se deve adicionar uma marca d'água \"Gerado por IA\" à imagem."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "Gere vídeo usando modelos ByteDance via API com base no prompt",
|
||||
"display_name": "ByteDance Texto para Vídeo",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "Gere imagens via Flux.2 [pro] ou Flux.2 [max] a partir de um prompt e imagens de referência opcionais.",
|
||||
"display_name": "Flux.2 Image",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "controle após gerar"
|
||||
},
|
||||
"model": {
|
||||
"name": "modelo"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "altura"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "largura"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Prompt para a geração ou edição da imagem"
|
||||
},
|
||||
"seed": {
|
||||
"name": "semente",
|
||||
"tooltip": "A semente aleatória usada para criar o ruído."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "Gera imagens de forma síncrona com base no prompt e na resolução.",
|
||||
"display_name": "Flux.2 [max] Imagem",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "Modifique uma imagem existente com base em um prompt de texto",
|
||||
"display_name": "Grok Image Edit",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "controle após gerar"
|
||||
},
|
||||
"model": {
|
||||
"name": "modelo"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "proporção"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "número_de_imagens"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "resolução"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "O prompt de texto usado para gerar a imagem"
|
||||
},
|
||||
"seed": {
|
||||
"name": "semente",
|
||||
"tooltip": "Semente para determinar se o nó deve ser executado novamente; os resultados reais são não determinísticos independentemente da semente."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "Gere imagens usando Grok com base em um prompt de texto",
|
||||
"display_name": "Grok Image",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "Gera imagens via endpoint GPT Image da OpenAI.",
|
||||
"display_name": "OpenAI GPT Image 2",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "controle após gerar"
|
||||
},
|
||||
"model": {
|
||||
"name": "modelo"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "fundo"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "altura_personalizada"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "largura_personalizada"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "qualidade"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "tamanho"
|
||||
},
|
||||
"n": {
|
||||
"name": "n",
|
||||
"tooltip": "Quantas imagens gerar"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Prompt de texto para o GPT Image"
|
||||
},
|
||||
"seed": {
|
||||
"name": "semente",
|
||||
"tooltip": "ainda não implementado no backend"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "Carrega e prepara arquivos de entrada (texto, pdf, etc.) para incluir como entradas no Nó de Chat da OpenAI. Os arquivos serão lidos pelo modelo OpenAI ao gerar uma resposta. 🛈 DICA: Pode ser encadeado com outros nós de Arquivo de Entrada OpenAI.",
|
||||
"display_name": "Arquivos de Entrada do OpenAI ChatGPT",
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "Унифицированная генерация изображений по тексту и точное редактирование по одному предложению с разрешением до 4K.",
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "fail_on_partial"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "height"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "max_images"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "size_preset"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "width"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Текстовый запрос для создания или редактирования изображения."
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "Сид для генерации."
|
||||
},
|
||||
"watermark": {
|
||||
"name": "watermark",
|
||||
"tooltip": "Добавлять ли водяной знак «AI generated» на изображение."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "Создать видео с использованием моделей ByteDance через API на основе промпта",
|
||||
"display_name": "ByteDance Текст в Видео",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "Генерация изображений с помощью Flux.2 [pro] или Flux.2 [max] по текстовому запросу и, при необходимости, референсным изображениям.",
|
||||
"display_name": "Flux.2 Image",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "height"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "width"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Запрос для генерации или редактирования изображения"
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "Случайный сид, используемый для создания шума."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "Генерирует изображения синхронно на основе запроса и разрешения.",
|
||||
"display_name": "Flux.2 [max] Image",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "Изменение существующего изображения на основе текстового запроса",
|
||||
"display_name": "Grok Image Edit",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "aspect_ratio"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "number_of_images"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "resolution"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Текстовый запрос, используемый для генерации изображения"
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "Сид для определения необходимости повторного запуска узла; фактические результаты не детерминированы независимо от сида."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "Генерировать изображения с помощью Grok на основе текстового запроса",
|
||||
"display_name": "Grok Image",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "Генерирует изображения через конечную точку OpenAI GPT Image.",
|
||||
"display_name": "OpenAI GPT Image 2",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "control after generate"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "background"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "custom_height"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "custom_width"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "quality"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "size"
|
||||
},
|
||||
"n": {
|
||||
"name": "n",
|
||||
"tooltip": "Сколько изображений сгенерировать"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Текстовый запрос для GPT Image"
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "еще не реализовано на сервере"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "Загружает и подготавливает входные файлы (текст, pdf и т.д.) для включения в качестве входных данных для узла Чат OpenAI. Файлы будут прочитаны моделью OpenAI при генерации ответа. 🛈 СОВЕТ: Может быть объединен в цепочку с другими узлами Входных файлов OpenAI.",
|
||||
"display_name": "Файлы ввода OpenAI ChatGPT",
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "Birleştirilmiş metinden-görüntüye üretim ve 4K çözünürlüğe kadar hassas tek cümle düzenleme.",
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "oluşturduktan sonra kontrol"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "kısmi başarısızlıkta dur"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "yükseklik"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "maksimum_görüntü"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "boyut_önayarı"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "genişlik"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "istem",
|
||||
"tooltip": "Bir görüntü oluşturmak veya düzenlemek için metin istemi."
|
||||
},
|
||||
"seed": {
|
||||
"name": "tohum",
|
||||
"tooltip": "Üretim için kullanılacak tohum."
|
||||
},
|
||||
"watermark": {
|
||||
"name": "filigran",
|
||||
"tooltip": "Görüntüye \"Yapay Zeka ile oluşturuldu\" filigranı eklenip eklenmeyeceği."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "Prompt'a dayalı olarak api üzerinden ByteDance modellerini kullanarak video oluştur",
|
||||
"display_name": "ByteDance Metinden Videoya",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "Bir istem ve isteğe bağlı referans görüntülerden Flux.2 [pro] veya Flux.2 [max] ile görüntüler oluşturun.",
|
||||
"display_name": "Flux.2 Görüntü",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "oluşturduktan sonra kontrol"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "yükseklik"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "genişlik"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "istem",
|
||||
"tooltip": "Görüntü oluşturma veya düzenleme için istem"
|
||||
},
|
||||
"seed": {
|
||||
"name": "tohum",
|
||||
"tooltip": "Gürültü oluşturmak için kullanılan rastgele tohum."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "İstem ve çözünürlüğe göre senkron bir şekilde görseller üretir.",
|
||||
"display_name": "Flux.2 [max] Görsel",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "Mevcut bir görüntüyü bir metin istemine göre değiştirin",
|
||||
"display_name": "Grok Görüntü Düzenleme",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "oluşturduktan sonra kontrol"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "en-boy_oranı"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "görüntü_sayısı"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "çözünürlük"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "istem",
|
||||
"tooltip": "Görüntü oluşturmak için kullanılan metin istemi"
|
||||
},
|
||||
"seed": {
|
||||
"name": "tohum",
|
||||
"tooltip": "Düğümün tekrar çalıştırılıp çalıştırılmayacağını belirlemek için tohum; gerçek sonuçlar tohumdan bağımsız olarak belirlenemezdir."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "Bir metin istemine göre Grok ile görüntüler oluştur",
|
||||
"display_name": "Grok Görüntü",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "OpenAI'nin GPT Görüntü uç noktası ile görüntüler oluşturur.",
|
||||
"display_name": "OpenAI GPT Görüntü 2",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "oluşturduktan sonra kontrol"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "arka_plan"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "özel_yükseklik"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "özel_genişlik"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "kalite"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "boyut"
|
||||
},
|
||||
"n": {
|
||||
"name": "n",
|
||||
"tooltip": "Kaç görüntü oluşturulacak"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "istem",
|
||||
"tooltip": "GPT Görüntü için metin istemi"
|
||||
},
|
||||
"seed": {
|
||||
"name": "tohum",
|
||||
"tooltip": "Henüz arka uçta uygulanmadı"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "OpenAI Sohbet Düğümü için girdi olarak eklemek üzere girdi dosyalarını (metin, pdf vb.) yükler ve hazırlar. Dosyalar, yanıt oluşturulurken OpenAI modeli tarafından okunacaktır. 🛈 İPUCU: Diğer OpenAI Girdi Dosyası düğümleriyle zincirlenebilir.",
|
||||
"display_name": "OpenAI ChatGPT Girdi Dosyaları",
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "統一的文字轉圖與精確單句編輯,最高支援 4K 解析度。",
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成後控制"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "部分失敗時終止"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "高度"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "最大圖像數"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "尺寸預設"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "寬度"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "提示詞",
|
||||
"tooltip": "用於創建或編輯圖像的文字提示。"
|
||||
},
|
||||
"seed": {
|
||||
"name": "種子",
|
||||
"tooltip": "用於生成的隨機種子。"
|
||||
},
|
||||
"watermark": {
|
||||
"name": "浮水印",
|
||||
"tooltip": "是否在圖像上添加「AI 生成」浮水印。"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "透過 API 使用字節跳動模型根據提示生成影片",
|
||||
"display_name": "字節跳動文字轉影片",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "透過 Flux.2 [pro] 或 Flux.2 [max],根據提示詞與可選參考圖像生成圖像。",
|
||||
"display_name": "Flux.2 圖像",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成後控制"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "高度"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "寬度"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "提示詞",
|
||||
"tooltip": "用於圖像生成或編輯的提示詞"
|
||||
},
|
||||
"seed": {
|
||||
"name": "種子",
|
||||
"tooltip": "用於產生雜訊的隨機種子。"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "根據提示詞與解析度同步生成圖像。",
|
||||
"display_name": "Flux.2 [max] 圖像",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "根據文字提示修改現有圖像",
|
||||
"display_name": "Grok 圖像編輯",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成後控制"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "長寬比"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "圖像數量"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "解析度"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "提示詞",
|
||||
"tooltip": "用於生成圖像的文字提示"
|
||||
},
|
||||
"seed": {
|
||||
"name": "種子",
|
||||
"tooltip": "決定節點是否重新執行的種子;實際結果無論種子如何皆為非確定性。"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "根據文字提示使用 Grok 生成圖像",
|
||||
"display_name": "Grok 圖像",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "透過 OpenAI 的 GPT Image 端點生成圖像。",
|
||||
"display_name": "OpenAI GPT 圖像 2",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成後控制"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "背景"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "自訂高度"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "自訂寬度"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "品質"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "尺寸"
|
||||
},
|
||||
"n": {
|
||||
"name": "數量",
|
||||
"tooltip": "要生成多少張圖像"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "提示詞",
|
||||
"tooltip": "GPT Image 的文字提示"
|
||||
},
|
||||
"seed": {
|
||||
"name": "種子",
|
||||
"tooltip": "後端尚未實作"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "載入並準備輸入文件(文字、pdf 等)以作為 OpenAI 聊天節點的輸入。生成回應時,OpenAI 模型將讀取這些文件。🛈 提示:可以與其他 OpenAI 輸入文件節點鏈接使用。",
|
||||
"display_name": "OpenAI ChatGPT 輸入文件",
|
||||
|
||||
@@ -953,6 +953,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceSeedreamNodeV2": {
|
||||
"description": "统一的文本生成图像与精确的单句编辑,最高支持4K分辨率。",
|
||||
"display_name": "ByteDance Seedream 4.5 & 5.0",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成后控制"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型"
|
||||
},
|
||||
"model_fail_on_partial": {
|
||||
"name": "部分失败时终止"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "高度"
|
||||
},
|
||||
"model_max_images": {
|
||||
"name": "最大图像数"
|
||||
},
|
||||
"model_size_preset": {
|
||||
"name": "尺寸预设"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "宽度"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "提示词",
|
||||
"tooltip": "用于创建或编辑图像的文本提示。"
|
||||
},
|
||||
"seed": {
|
||||
"name": "种子",
|
||||
"tooltip": "用于生成的种子。"
|
||||
},
|
||||
"watermark": {
|
||||
"name": "水印",
|
||||
"tooltip": "是否在图像上添加“AI生成”水印。"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ByteDanceTextToVideoNode": {
|
||||
"description": "通过API基于提示使用字节跳动模型生成视频",
|
||||
"display_name": "字节跳动文生视频",
|
||||
@@ -3432,6 +3476,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2ImageNode": {
|
||||
"description": "通过Flux.2 [pro]或Flux.2 [max],根据提示词和可选参考图像生成图像。",
|
||||
"display_name": "Flux.2 图像",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成后控制"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型"
|
||||
},
|
||||
"model_height": {
|
||||
"name": "高度"
|
||||
},
|
||||
"model_width": {
|
||||
"name": "宽度"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "提示词",
|
||||
"tooltip": "用于图像生成或编辑的提示词"
|
||||
},
|
||||
"seed": {
|
||||
"name": "种子",
|
||||
"tooltip": "用于生成噪声的随机种子。"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"Flux2MaxImageNode": {
|
||||
"description": "根据提示词和分辨率同步生成图像。",
|
||||
"display_name": "Flux.2 [max] 图像",
|
||||
@@ -4455,6 +4530,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageEditNodeV2": {
|
||||
"description": "根据文本提示修改已有图像",
|
||||
"display_name": "Grok 图像编辑",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成后控制"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型"
|
||||
},
|
||||
"model_aspect_ratio": {
|
||||
"name": "宽高比"
|
||||
},
|
||||
"model_number_of_images": {
|
||||
"name": "图像数量"
|
||||
},
|
||||
"model_resolution": {
|
||||
"name": "分辨率"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "提示词",
|
||||
"tooltip": "用于生成图像的文本提示"
|
||||
},
|
||||
"seed": {
|
||||
"name": "种子",
|
||||
"tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"GrokImageNode": {
|
||||
"description": "使用 Grok 根据文本提示生成图像",
|
||||
"display_name": "Grok 图像",
|
||||
@@ -11965,6 +12074,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIGPTImageNodeV2": {
|
||||
"description": "通过OpenAI的GPT Image端点生成图像。",
|
||||
"display_name": "OpenAI GPT 图像 2",
|
||||
"inputs": {
|
||||
"control_after_generate": {
|
||||
"name": "生成后控制"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型"
|
||||
},
|
||||
"model_background": {
|
||||
"name": "背景"
|
||||
},
|
||||
"model_custom_height": {
|
||||
"name": "自定义高度"
|
||||
},
|
||||
"model_custom_width": {
|
||||
"name": "自定义宽度"
|
||||
},
|
||||
"model_quality": {
|
||||
"name": "质量"
|
||||
},
|
||||
"model_size": {
|
||||
"name": "尺寸"
|
||||
},
|
||||
"n": {
|
||||
"name": "数量",
|
||||
"tooltip": "要生成的图像数量"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "提示词",
|
||||
"tooltip": "用于GPT Image的文本提示"
|
||||
},
|
||||
"seed": {
|
||||
"name": "种子",
|
||||
"tooltip": "后端尚未实现"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"tooltip": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIInputFiles": {
|
||||
"description": "加载并准备输入文件(文本、PDF等)作为OpenAI聊天节点的输入。生成响应时,OpenAI模型将读取这些文件。🛈 提示:可与其他OpenAI输入文件节点链式连接。",
|
||||
"display_name": "OpenAI ChatGPT Input Files",
|
||||
|
||||
@@ -197,5 +197,18 @@ export const MODEL_NODE_MAPPINGS: ReadonlyArray<
|
||||
['mediapipe', 'LivePortraitLoadMediaPipeCropper', ''],
|
||||
|
||||
// ---- Superprompt text enhancement ----
|
||||
['superprompt-v1', 'Superprompt', '']
|
||||
['superprompt-v1', 'Superprompt', ''],
|
||||
|
||||
// ---- ComfyUI core background removal (v0.21+) ----
|
||||
['background_removal', 'LoadBackgroundRemovalModel', 'bg_removal_name'],
|
||||
|
||||
// ---- ComfyUI core frame interpolation (v0.21+) ----
|
||||
['frame_interpolation', 'FrameInterpolationModelLoader', 'model_name'],
|
||||
|
||||
// ---- FILM frame interpolation (ComfyUI-Frame-Interpolation) ----
|
||||
['film', 'FILM VFI', 'ckpt_name'],
|
||||
|
||||
// ---- Ultralytics YOLO detectors (ComfyUI-Impact-Pack) ----
|
||||
['ultralytics/bbox', 'UltralyticsDetectorProvider', 'model_name'],
|
||||
['ultralytics/segm', 'UltralyticsDetectorProvider', 'model_name']
|
||||
] as const satisfies ReadonlyArray<readonly [string, string, string]>
|
||||
|
||||
@@ -38,6 +38,17 @@ export const CORE_SETTINGS: SettingParams[] = [
|
||||
options: ['default', 'v1 (legacy)', 'litegraph (legacy)'],
|
||||
defaultValue: 'default'
|
||||
},
|
||||
{
|
||||
id: 'Comfy.NodeSearchBox.ReplaceCanvasMenu',
|
||||
category: ['Comfy', 'Node Search Box', 'ReplaceCanvasMenu'],
|
||||
experimental: true,
|
||||
name: 'Replace canvas right-click "Add Node" with search box',
|
||||
tooltip:
|
||||
'When enabled, the right-click canvas menu opens the node search box instead of the LiteGraph category submenu. The search box includes blueprints, partner nodes, core nodes, and extensions.',
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
versionAdded: '1.46.0'
|
||||
},
|
||||
{
|
||||
id: 'Comfy.LinkRelease.Action',
|
||||
category: ['LiteGraph', 'LinkRelease', 'Action'],
|
||||
|
||||
@@ -344,6 +344,7 @@ const zSettings = z.object({
|
||||
'Comfy.NodeSearchBoxImpl.ShowCategory': z.boolean(),
|
||||
'Comfy.NodeSearchBoxImpl.ShowIdName': z.boolean(),
|
||||
'Comfy.NodeSearchBoxImpl.ShowNodeFrequency': z.boolean(),
|
||||
'Comfy.NodeSearchBox.ReplaceCanvasMenu': z.boolean(),
|
||||
'Comfy.NodeSuggestions.number': z.number(),
|
||||
'Comfy.Node.BypassAllLinksOnDelete': z.boolean(),
|
||||
'Comfy.Node.Opacity': z.number(),
|
||||
|
||||
@@ -26,9 +26,6 @@ vi.mock('@/platform/settings/settingStore', () => ({
|
||||
useSettingStore: () => mockSettingStore
|
||||
}))
|
||||
|
||||
//@ts-expect-error Define global for the test
|
||||
global.__COMFYUI_FRONTEND_VERSION__ = '1.24.0'
|
||||
|
||||
import { useNewUserService } from '@/services/useNewUserService'
|
||||
|
||||
describe('useNewUserService', () => {
|
||||
@@ -120,6 +117,73 @@ describe('useNewUserService', () => {
|
||||
expect(service.isNewUser()).toBe(false)
|
||||
})
|
||||
|
||||
it('should identify existing user when V1 draft store keys exist', async () => {
|
||||
mockSettingStore.settingValues = {}
|
||||
mockSettingStore.get.mockReturnValue(undefined)
|
||||
mockLocalStorage.getItem.mockImplementation((key: string) => {
|
||||
if (key === 'Comfy.Workflow.Drafts') return '{}'
|
||||
return null
|
||||
})
|
||||
|
||||
await service.initializeIfNewUser()
|
||||
|
||||
expect(service.isNewUser()).toBe(false)
|
||||
})
|
||||
|
||||
it('should identify existing user when V1 draft order key exists', async () => {
|
||||
mockSettingStore.settingValues = {}
|
||||
mockSettingStore.get.mockReturnValue(undefined)
|
||||
mockLocalStorage.getItem.mockImplementation((key: string) => {
|
||||
if (key === 'Comfy.Workflow.DraftOrder') return '[]'
|
||||
return null
|
||||
})
|
||||
|
||||
await service.initializeIfNewUser()
|
||||
|
||||
expect(service.isNewUser()).toBe(false)
|
||||
})
|
||||
|
||||
it('should identify existing user when V2 draft index has entries', async () => {
|
||||
mockSettingStore.settingValues = {}
|
||||
mockSettingStore.get.mockReturnValue(undefined)
|
||||
mockLocalStorage.getItem.mockImplementation((key: string) => {
|
||||
if (key === 'Comfy.Workflow.DraftIndex.v2:personal')
|
||||
return '{"v":2,"updatedAt":1,"order":["abc"],"entries":{"abc":{"path":"workflows/Untitled.json","name":"Untitled","isTemporary":true,"updatedAt":1}}}'
|
||||
return null
|
||||
})
|
||||
|
||||
await service.initializeIfNewUser()
|
||||
|
||||
expect(service.isNewUser()).toBe(false)
|
||||
})
|
||||
|
||||
it('should identify new user when V2 draft index exists but is empty', async () => {
|
||||
mockSettingStore.settingValues = {}
|
||||
mockSettingStore.get.mockReturnValue(undefined)
|
||||
mockLocalStorage.getItem.mockImplementation((key: string) => {
|
||||
if (key === 'Comfy.Workflow.DraftIndex.v2:personal')
|
||||
return '{"v":2,"updatedAt":1,"order":[],"entries":{}}'
|
||||
return null
|
||||
})
|
||||
|
||||
await service.initializeIfNewUser()
|
||||
|
||||
expect(service.isNewUser()).toBe(true)
|
||||
})
|
||||
|
||||
it('should identify new user when V2 draft index is malformed', async () => {
|
||||
mockSettingStore.settingValues = {}
|
||||
mockSettingStore.get.mockReturnValue(undefined)
|
||||
mockLocalStorage.getItem.mockImplementation((key: string) => {
|
||||
if (key === 'Comfy.Workflow.DraftIndex.v2:personal') return 'not json'
|
||||
return null
|
||||
})
|
||||
|
||||
await service.initializeIfNewUser()
|
||||
|
||||
expect(service.isNewUser()).toBe(true)
|
||||
})
|
||||
|
||||
it('should identify new user when tutorial is explicitly false', async () => {
|
||||
mockSettingStore.settingValues = { 'Comfy.TutorialCompleted': false }
|
||||
mockSettingStore.get.mockImplementation((key: string) => {
|
||||
|
||||
@@ -2,6 +2,24 @@ import { ref, shallowRef } from 'vue'
|
||||
import { createSharedComposable } from '@vueuse/core'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
|
||||
function hasV2DraftHistory(raw: string | null): boolean {
|
||||
if (!raw) return false
|
||||
try {
|
||||
const parsed = JSON.parse(raw) as {
|
||||
order?: unknown
|
||||
entries?: unknown
|
||||
}
|
||||
const orderLength = Array.isArray(parsed.order) ? parsed.order.length : 0
|
||||
const entriesCount =
|
||||
parsed.entries && typeof parsed.entries === 'object'
|
||||
? Object.keys(parsed.entries as Record<string, unknown>).length
|
||||
: 0
|
||||
return orderLength > 0 || entriesCount > 0
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function _useNewUserService() {
|
||||
const settingStore = useSettingStore()
|
||||
const pendingCallbacks = shallowRef<Array<() => Promise<void>>>([])
|
||||
@@ -18,12 +36,32 @@ function _useNewUserService() {
|
||||
const isNewUserSettings =
|
||||
Object.keys(settingStore.settingValues).length === 0 ||
|
||||
!settingStore.get('Comfy.TutorialCompleted')
|
||||
const hasNoWorkflow = !localStorage.getItem('workflow')
|
||||
const hasNoPreviousWorkflow = !localStorage.getItem(
|
||||
'Comfy.PreviousWorkflow'
|
||||
|
||||
// Legacy keys (pre-V1 and V1 persistence)
|
||||
const hasNoLegacyWorkflow =
|
||||
!localStorage.getItem('workflow') &&
|
||||
!localStorage.getItem('Comfy.PreviousWorkflow')
|
||||
|
||||
// V1 draft store keys
|
||||
const hasNoV1Drafts =
|
||||
!localStorage.getItem('Comfy.Workflow.Drafts') &&
|
||||
!localStorage.getItem('Comfy.Workflow.DraftOrder')
|
||||
|
||||
// V2 draft index key (scoped to personal workspace; cloud workspace id
|
||||
// comes from sessionStorage which may not be set yet at this point).
|
||||
// Check for actual draft history rather than key existence: an empty
|
||||
// index is written by `migrateV1toV2()` for genuine new users during
|
||||
// startup, so key presence alone is not evidence of prior usage.
|
||||
const hasNoV2DraftIndex = !hasV2DraftHistory(
|
||||
localStorage.getItem('Comfy.Workflow.DraftIndex.v2:personal')
|
||||
)
|
||||
|
||||
return isNewUserSettings && hasNoWorkflow && hasNoPreviousWorkflow
|
||||
return (
|
||||
isNewUserSettings &&
|
||||
hasNoLegacyWorkflow &&
|
||||
hasNoV1Drafts &&
|
||||
hasNoV2DraftIndex
|
||||
)
|
||||
}
|
||||
|
||||
async function registerInitCallback(callback: () => Promise<void>) {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { setActivePinia } from 'pinia'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type NodeSearchBoxPopover from '@/components/searchbox/NodeSearchBoxPopover.vue'
|
||||
import type { CanvasPointerEvent } from '@/lib/litegraph/src/litegraph'
|
||||
import type { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useSearchBoxStore } from '@/stores/workspace/searchBoxStore'
|
||||
|
||||
@@ -135,4 +136,43 @@ describe('useSearchBoxStore', () => {
|
||||
expect(store.visible).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('openAtEvent', () => {
|
||||
const event = {
|
||||
canvasX: 123,
|
||||
canvasY: 456
|
||||
} as unknown as CanvasPointerEvent
|
||||
|
||||
it('forwards the event to the popover when one is registered', () => {
|
||||
vi.mocked(mockSettingStore.get).mockReturnValue('default')
|
||||
const store = useSearchBoxStore()
|
||||
const mockPopover = createMockPopover()
|
||||
store.setPopoverRef(mockPopover)
|
||||
|
||||
store.openAtEvent(event)
|
||||
|
||||
expect(vi.mocked(mockPopover.showSearchBox)).toHaveBeenCalledWith(event)
|
||||
expect(store.visible).toBe(false)
|
||||
})
|
||||
|
||||
it('falls back to showing the new search box when no popover is registered', () => {
|
||||
vi.mocked(mockSettingStore.get).mockReturnValue('default')
|
||||
const store = useSearchBoxStore()
|
||||
store.setPopoverRef(null)
|
||||
|
||||
store.openAtEvent(event)
|
||||
|
||||
expect(store.visible).toBe(true)
|
||||
})
|
||||
|
||||
it('does nothing when the legacy litegraph search box is selected and no popover is registered', () => {
|
||||
vi.mocked(mockSettingStore.get).mockReturnValue('litegraph (legacy)')
|
||||
const store = useSearchBoxStore()
|
||||
store.setPopoverRef(null)
|
||||
|
||||
store.openAtEvent(event)
|
||||
|
||||
expect(store.visible).toBe(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -45,11 +45,22 @@ export const useSearchBoxStore = defineStore('searchBox', () => {
|
||||
)
|
||||
}
|
||||
|
||||
function openAtEvent(event: CanvasPointerEvent) {
|
||||
if (popoverRef.value) {
|
||||
popoverRef.value.showSearchBox(event)
|
||||
return
|
||||
}
|
||||
if (newSearchBoxEnabled.value) {
|
||||
visible.value = true
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
useSearchBoxV2,
|
||||
newSearchBoxEnabled,
|
||||
setPopoverRef,
|
||||
toggleVisible,
|
||||
openAtEvent,
|
||||
visible
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user