mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-13 17:10:06 +00:00
Move price badges to python nodes (#7816)
## Summary Backend part: https://github.com/Comfy-Org/ComfyUI/pull/11582 - Move API node pricing definitions from hardcoded frontend functions to backend-defined JSONata expressions - Add `price_badge` field to node definition schema containing JSONata expression and dependency declarations - Implement async JSONata evaluation with signature-based caching for efficient reactive updates - Show one decimal in credit badges when meaningful (e.g., 1.5 credits instead of 2 credits) ## Screenshots (if applicable) <!-- Add screenshots or video recording to help explain your changes --> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7816-Move-price-badges-to-python-nodes-2da6d73d365081ec815ef61f7e3c65f7) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -197,6 +197,50 @@ const zComfyOutputTypesSpec = z.array(
|
||||
z.union([zComfyNodeDataType, zComfyComboOutput])
|
||||
)
|
||||
|
||||
/**
|
||||
* Widget dependency with type information.
|
||||
* Provides strong type enforcement for JSONata evaluation context.
|
||||
*/
|
||||
const zWidgetDependency = z.object({
|
||||
name: z.string(),
|
||||
type: z.string()
|
||||
})
|
||||
|
||||
export type WidgetDependency = z.infer<typeof zWidgetDependency>
|
||||
|
||||
/**
|
||||
* Schema for price badge depends_on field.
|
||||
* Specifies which widgets and inputs the pricing expression depends on.
|
||||
* Widgets must be specified as objects with name and type.
|
||||
*/
|
||||
const zPriceBadgeDepends = z.object({
|
||||
widgets: z.array(zWidgetDependency).optional().default([]),
|
||||
inputs: z.array(z.string()).optional().default([]),
|
||||
/**
|
||||
* Autogrow input group names to track.
|
||||
* For each group, the count of connected inputs will be available in the
|
||||
* JSONata context as `g.<groupName>`.
|
||||
* Example: `input_groups: ["reference_videos"]` makes `g.reference_videos`
|
||||
* available with the count of connected inputs like `reference_videos.character1`, etc.
|
||||
*/
|
||||
input_groups: z.array(z.string()).optional().default([])
|
||||
})
|
||||
|
||||
/**
|
||||
* Schema for price badge definition.
|
||||
* Used to calculate and display pricing information for API nodes.
|
||||
* The `expr` field contains a JSONata expression that returns a PricingResult.
|
||||
*/
|
||||
const zPriceBadge = z.object({
|
||||
engine: z.literal('jsonata').optional().default('jsonata'),
|
||||
depends_on: zPriceBadgeDepends
|
||||
.optional()
|
||||
.default({ widgets: [], inputs: [], input_groups: [] }),
|
||||
expr: z.string()
|
||||
})
|
||||
|
||||
export type PriceBadge = z.infer<typeof zPriceBadge>
|
||||
|
||||
export const zComfyNodeDef = z.object({
|
||||
input: zComfyInputsSpec.optional(),
|
||||
output: zComfyOutputTypesSpec.optional(),
|
||||
@@ -224,7 +268,13 @@ export const zComfyNodeDef = z.object({
|
||||
* Used to ensure consistent widget ordering regardless of JSON serialization.
|
||||
* Keys are 'required', 'optional', etc., values are arrays of input names.
|
||||
*/
|
||||
input_order: z.record(z.array(z.string())).optional()
|
||||
input_order: z.record(z.array(z.string())).optional(),
|
||||
/**
|
||||
* Price badge definition for API nodes.
|
||||
* Contains a JSONata expression to calculate pricing based on widget values
|
||||
* and input connectivity.
|
||||
*/
|
||||
price_badge: zPriceBadge.optional()
|
||||
})
|
||||
|
||||
export const zAutogrowOptions = z.object({
|
||||
|
||||
Reference in New Issue
Block a user