feat: support custom descriptions for subgraph tooltips (#9003)

## Summary

Adds support for custom descriptions on subgraph nodes that display as
tooltips when hovering.

## Changes

- Add optional `description` field to `ExportedSubgraph` interface and
`Subgraph` class
- Use description with fallback to default string in
`subgraphService.createNodeDef()`
- Add `description` to `SubgraphDefinitionBase` interface and Zod schema
for validation

## Review Focus

- Backwards compatibility: undefined description falls back to `Subgraph
node for ${name}`
- Serialization pattern: conditional spread `...(this.description && {
description })`

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9003-feat-support-custom-descriptions-for-subgraph-tooltips-30d6d73d36508129bd75c77eb1c31cfb)
by [Unito](https://www.unito.io)
This commit is contained in:
Christian Byrne
2026-02-21 22:29:28 -08:00
committed by GitHub
parent 2639248867
commit d2917be3a7
5 changed files with 12 additions and 3 deletions

View File

@@ -2657,6 +2657,8 @@ export class Subgraph
/** The display name of the subgraph. */
name: string = 'Unnamed Subgraph'
/** Optional description shown as tooltip when hovering over the subgraph node. */
description?: string
readonly inputNode = new SubgraphInputNode(this)
readonly outputNode = new SubgraphOutputNode(this)
@@ -2707,9 +2709,10 @@ export class Subgraph
| (ISerialisedGraph & ExportedSubgraph)
| (SerialisableGraph & ExportedSubgraph)
): void {
const { name, inputs, outputs, widgets } = data
const { name, description, inputs, outputs, widgets } = data
this.name = name
this.description = description
if (inputs) {
this.inputs.length = 0
for (const input of inputs) {
@@ -2920,6 +2923,7 @@ export class Subgraph
revision: this.revision,
config: this.config,
name: this.name,
...(this.description && { description: this.description }),
inputNode: this.inputNode.asSerialisable(),
outputNode: this.outputNode.asSerialisable(),
inputs: this.inputs.map((x) => x.asSerialisable()),

View File

@@ -76,7 +76,6 @@ describe.skip('SubgraphSerialization - Basic Serialization', () => {
// Verify core properties
expect(restored.id).toBe(original.id)
expect(restored.name).toBe(original.name)
// @ts-expect-error description property not in type definition
expect(restored.description).toBe(original.description)
// Verify I/O structure

View File

@@ -139,6 +139,8 @@ export interface ExportedSubgraph extends SerialisableGraph {
name: string
/** Optional category for organizing subgraph blueprints in the node library. */
category?: string
/** Optional description shown as tooltip when hovering over the subgraph node. */
description?: string
inputNode: ExportedSubgraphIONode
outputNode: ExportedSubgraphIONode
/** Ordered list of inputs to the subgraph itself. Similar to a reroute, with the input side in the graph, and the output side in the subgraph. */

View File

@@ -396,6 +396,8 @@ interface SubgraphDefinitionBase<
id: string
revision: number
name: string
/** Optional description shown as tooltip when hovering over the subgraph node. */
description?: string
category?: string
/** Custom metadata for the subgraph (description, searchAliases, etc.) */
extra?: T extends ComfyWorkflow1BaseInput
@@ -432,6 +434,8 @@ const zSubgraphDefinition = zComfyWorkflow1
id: z.string().uuid(),
revision: z.number(),
name: z.string(),
/** Optional description shown as tooltip when hovering over the subgraph node. */
description: z.string().optional(),
category: z.string().optional(),
inputNode: zExportedSubgraphIONode,
outputNode: zExportedSubgraphIONode,

View File

@@ -49,7 +49,7 @@ export const useSubgraphService = () => {
output_tooltips: [],
name: id,
display_name: name,
description: `Subgraph node for ${name}`,
description: exportedSubgraph.description || `Subgraph node for ${name}`,
category: 'subgraph',
output_node: false,
python_module: 'nodes'