Node Types

Status: 200 OK

API: https://catalog.chengos.dev/api/v1/nodes/types

Generated At: 2026-05-10T05:29:11.945Z

Source: Catalog API Docs

{
  "data": [
    {
      "typeId": "chat/output",
      "name": "Chat Output Node",
      "category": "chat",
      "description": "Receive message packets and render to chat interface, supports streaming display, virtualization and message export",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "ChatOutputNode 输入 直接接受 Agent 最终回复文本和执行轨迹,简化前端解析",
        "properties": {
          "autoscroll": {
            "default": true,
            "description": "Auto scroll to latest message",
            "title": "Auto Scroll",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.chat.output.inputs.autoscroll"
          },
          "context": {
            "additionalProperties": true,
            "description": "Agent final reply text or AgentContext (auto extracts text)",
            "title": "Agent Reply",
            "type": "object",
            "x-i18n-key": "nodes.chat.output.inputs.context",
            "x-port": true
          },
          "display_format": {
            "default": "standard",
            "description": "Message display format",
            "oneOf": [
              {
                "description": "紧凑模式",
                "enum": [
                  "compact"
                ],
                "type": "string"
              },
              {
                "description": "标准模式",
                "enum": [
                  "standard"
                ],
                "type": "string"
              },
              {
                "description": "详细模式",
                "enum": [
                  "detailed"
                ],
                "type": "string"
              }
            ],
            "title": "Display Format",
            "x-control": "select",
            "x-i18n-key": "nodes.chat.output.inputs.display_format"
          },
          "keep_messages": {
            "default": 1000,
            "description": "Maximum messages to keep in memory",
            "format": "uint",
            "maximum": 10000,
            "minimum": 10,
            "title": "Keep Messages",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.chat.output.inputs.keep_messages"
          },
          "show_timestamp": {
            "default": true,
            "description": "Show message timestamp",
            "title": "Show Timestamp",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.chat.output.inputs.show_timestamp"
          },
          "theme": {
            "default": "system",
            "description": "Display theme",
            "enum": [
              "light",
              "dark",
              "system"
            ],
            "options": [
              {
                "label": "light",
                "value": "light"
              },
              {
                "label": "dark",
                "value": "dark"
              },
              {
                "label": "system",
                "value": "system"
              }
            ],
            "title": "Theme",
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.chat.output.inputs.theme"
          },
          "trace": {
            "default": null,
            "description": "Agent execution trace (thinking process)",
            "title": "Trace",
            "type": "string",
            "x-i18n-key": "nodes.chat.output.inputs.trace",
            "x-port": true
          },
          "virtualize_threshold": {
            "default": 100,
            "description": "Enable virtualization when message count exceeds this value",
            "format": "uint",
            "maximum": 1000,
            "minimum": 10,
            "title": "Virtualize Threshold",
            "type": "integer",
            "x-control": "slider",
            "x-i18n-key": "nodes.chat.output.inputs.virtualize_threshold"
          }
        },
        "required": [
          "context"
        ],
        "title": "ChatOutputNodeInput",
        "type": "object",
        "x-field-order": [
          "context",
          "trace",
          "theme",
          "autoscroll",
          "keep_messages",
          "virtualize_threshold",
          "display_format",
          "show_timestamp"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AppendMode": {
            "description": "追加模式",
            "oneOf": [
              {
                "description": "平滑追加(带动画)",
                "enum": [
                  "smooth"
                ],
                "type": "string"
              },
              {
                "description": "即时追加",
                "enum": [
                  "instant"
                ],
                "type": "string"
              }
            ]
          },
          "ChatAppendPayload": {
            "description": "ChatAppend 事件载荷",
            "properties": {
              "append_mode": {
                "allOf": [
                  {
                    "$ref": "#/definitions/AppendMode"
                  }
                ],
                "description": "追加模式"
              },
              "packets": {
                "description": "要追加的消息列表",
                "items": {
                  "$ref": "#/definitions/MessagePacket"
                },
                "type": "array"
              },
              "scroll_hint": {
                "allOf": [
                  {
                    "$ref": "#/definitions/ScrollHint"
                  }
                ],
                "description": "滚动提示"
              }
            },
            "required": [
              "append_mode",
              "packets",
              "scroll_hint"
            ],
            "type": "object"
          },
          "ChatMetaPayload": {
            "description": "ChatMeta 事件载荷",
            "properties": {
              "action": {
                "allOf": [
                  {
                    "$ref": "#/definitions/MetaAction"
                  }
                ],
                "description": "元操作类型"
              },
              "data": {
                "description": "附加数据"
              }
            },
            "required": [
              "action"
            ],
            "type": "object"
          },
          "ChatPatchPayload": {
            "description": "ChatPatch 事件载荷",
            "properties": {
              "message_id": {
                "description": "要更新的消息 ID",
                "type": "string"
              },
              "patch": {
                "allOf": [
                  {
                    "$ref": "#/definitions/MessagePacket"
                  }
                ],
                "description": "更新内容"
              }
            },
            "required": [
              "message_id",
              "patch"
            ],
            "type": "object"
          },
          "ChatUiEvent": {
            "description": "UI 事件类型",
            "oneOf": [
              {
                "description": "追加消息",
                "properties": {
                  "payload": {
                    "$ref": "#/definitions/ChatAppendPayload"
                  },
                  "type": {
                    "enum": [
                      "ChatAppend"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "payload",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "局部更新(替换某条消息)",
                "properties": {
                  "payload": {
                    "$ref": "#/definitions/ChatPatchPayload"
                  },
                  "type": {
                    "enum": [
                      "ChatPatch"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "payload",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "元信息变更(滚动、主题、清屏、状态)",
                "properties": {
                  "payload": {
                    "$ref": "#/definitions/ChatMetaPayload"
                  },
                  "type": {
                    "enum": [
                      "ChatMeta"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "payload",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "MessagePacket": {
            "description": "消息包 - Chat 系统的核心数据结构",
            "properties": {
              "hash": {
                "description": "Message hash (for deduplication and idempotency)",
                "pattern": "^[0-9a-f]{32}$",
                "title": "Hash",
                "type": "string"
              },
              "id": {
                "description": "Unique message ID",
                "title": "ID",
                "type": "string"
              },
              "meta": {
                "additionalProperties": true,
                "description": "Message metadata",
                "title": "Meta",
                "type": "object"
              },
              "msg_type": {
                "allOf": [
                  {
                    "$ref": "#/definitions/MessageType"
                  }
                ],
                "description": "Message type (text/image/file/audio, etc.)",
                "title": "Msg Type"
              },
              "payload": {
                "description": "Message content payload",
                "title": "Payload"
              },
              "protocol_version": {
                "description": "Protocol version",
                "title": "Protocol Version",
                "type": "string"
              },
              "stream_hint": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/StreamHint"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Stream shard info",
                "title": "Stream Hint"
              },
              "timestamp": {
                "description": "Message creation timestamp (Unix ms)",
                "format": "int64",
                "title": "Timestamp",
                "type": "integer"
              }
            },
            "required": [
              "hash",
              "id",
              "meta",
              "msg_type",
              "payload",
              "protocol_version",
              "timestamp"
            ],
            "type": "object"
          },
          "MessageType": {
            "description": "消息类型",
            "oneOf": [
              {
                "description": "纯文本",
                "enum": [
                  "text"
                ],
                "type": "string"
              },
              {
                "description": "图片",
                "enum": [
                  "image"
                ],
                "type": "string"
              },
              {
                "description": "文件",
                "enum": [
                  "file"
                ],
                "type": "string"
              },
              {
                "description": "音频",
                "enum": [
                  "audio"
                ],
                "type": "string"
              },
              {
                "description": "视频",
                "enum": [
                  "video"
                ],
                "type": "string"
              },
              {
                "description": "OCR 识别结果",
                "enum": [
                  "ocr_text"
                ],
                "type": "string"
              },
              {
                "description": "流式分片",
                "enum": [
                  "stream"
                ],
                "type": "string"
              },
              {
                "description": "控制消息(如清屏、状态变更)",
                "enum": [
                  "control"
                ],
                "type": "string"
              },
              {
                "description": "错误消息",
                "enum": [
                  "error"
                ],
                "type": "string"
              },
              {
                "description": "网页快照",
                "enum": [
                  "web_snapshot"
                ],
                "type": "string"
              },
              {
                "description": "系统消息",
                "enum": [
                  "system"
                ],
                "type": "string"
              }
            ]
          },
          "MetaAction": {
            "description": "元操作类型",
            "oneOf": [
              {
                "description": "清屏",
                "enum": [
                  "clear"
                ],
                "type": "string"
              },
              {
                "description": "滚动到底部",
                "enum": [
                  "scroll_to_bottom"
                ],
                "type": "string"
              },
              {
                "description": "滚动到顶部",
                "enum": [
                  "scroll_to_top"
                ],
                "type": "string"
              },
              {
                "additionalProperties": false,
                "description": "滚动到指定消息",
                "properties": {
                  "scroll_to_message": {
                    "properties": {
                      "message_id": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "message_id"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "scroll_to_message"
                ],
                "type": "object"
              },
              {
                "additionalProperties": false,
                "description": "切换主题",
                "properties": {
                  "set_theme": {
                    "properties": {
                      "theme": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "theme"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "set_theme"
                ],
                "type": "object"
              },
              {
                "description": "显示加载骨架",
                "enum": [
                  "show_skeleton"
                ],
                "type": "string"
              },
              {
                "description": "隐藏加载骨架",
                "enum": [
                  "hide_skeleton"
                ],
                "type": "string"
              },
              {
                "additionalProperties": false,
                "description": "节点状态变更",
                "properties": {
                  "status_change": {
                    "properties": {
                      "status": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "status"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "status_change"
                ],
                "type": "object"
              }
            ]
          },
          "OutputStats": {
            "description": "输出统计",
            "properties": {
              "displayed": {
                "format": "uint",
                "minimum": 0,
                "title": "Displayed",
                "type": "integer"
              },
              "errors": {
                "format": "uint",
                "minimum": 0,
                "title": "Errors",
                "type": "integer"
              },
              "migrated": {
                "format": "uint",
                "minimum": 0,
                "title": "Migrated",
                "type": "integer"
              },
              "received": {
                "format": "uint",
                "minimum": 0,
                "title": "Received",
                "type": "integer"
              }
            },
            "required": [
              "displayed",
              "errors",
              "migrated",
              "received"
            ],
            "type": "object"
          },
          "ScrollHint": {
            "description": "滚动提示",
            "oneOf": [
              {
                "description": "自动滚动到底部",
                "enum": [
                  "auto"
                ],
                "type": "string"
              },
              {
                "description": "锁定当前位置",
                "enum": [
                  "lock"
                ],
                "type": "string"
              }
            ]
          },
          "StreamHint": {
            "description": "流式分片提示",
            "properties": {
              "chunk_index": {
                "description": "分片索引(从 0 开始)",
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "group_id": {
                "description": "所属消息组 ID",
                "type": "string"
              },
              "is_final": {
                "description": "是否为最后一个分片",
                "type": "boolean"
              }
            },
            "required": [
              "chunk_index",
              "group_id",
              "is_final"
            ],
            "type": "object"
          }
        },
        "description": "ChatOutputNode 输出",
        "properties": {
          "message_count": {
            "description": "Current total messages retained",
            "format": "uint",
            "minimum": 0,
            "title": "Message Count",
            "type": "integer",
            "x-i18n-key": "nodes.chat.output.outputs.message_count"
          },
          "reply": {
            "description": "Assistant final reply text content",
            "title": "Reply",
            "type": "string",
            "x-i18n-key": "nodes.chat.output.outputs.reply"
          },
          "stats": {
            "allOf": [
              {
                "$ref": "#/definitions/OutputStats"
              }
            ],
            "description": "Processing statistics",
            "title": "Stats",
            "x-i18n-key": "nodes.chat.output.outputs.stats"
          },
          "trace": {
            "description": "Agent execution trace (thinking process)",
            "title": "Trace",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.chat.output.outputs.trace"
          },
          "ui_events": {
            "description": "UI events to send to frontend",
            "items": {
              "$ref": "#/definitions/ChatUiEvent"
            },
            "title": "Ui Events",
            "type": "array",
            "x-i18n-key": "nodes.chat.output.outputs.ui_events"
          },
          "virtualized": {
            "description": "Whether virtualization rendering is enabled",
            "title": "Virtualized",
            "type": "boolean",
            "x-i18n-key": "nodes.chat.output.outputs.virtualized"
          }
        },
        "required": [
          "message_count",
          "reply",
          "stats",
          "ui_events",
          "virtualized"
        ],
        "title": "ChatOutputNodeOutput",
        "type": "object",
        "x-collapsed-visible": [
          "reply"
        ],
        "x-field-order": [
          "reply",
          "trace",
          "ui_events",
          "message_count",
          "virtualized",
          "stats"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.chat.output"
    },
    {
      "typeId": "io/input_text",
      "name": "Text Input",
      "category": "io",
      "description": "Multi-line text / JSON input, outputs text, JSON value and AgentContext",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "json_text": {
            "default": "",
            "description": "JSON format content (ignored when empty)",
            "maxLength": 200000,
            "minLength": 0,
            "title": "JSON",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.io.input_text.inputs.json_text",
            "x-language": "json",
            "x-rows": 2
          },
          "text": {
            "default": "",
            "description": "Plain text content (supports multi-line input)",
            "maxLength": 200000,
            "minLength": 0,
            "title": "Text",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.io.input_text.inputs.text"
          }
        },
        "title": "InputTextInput",
        "type": "object",
        "x-collapsed-visible": [
          "text",
          "json_text"
        ],
        "x-field-order": [
          "text",
          "json_text"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "context": {
            "additionalProperties": true,
            "description": "AgentContext output (can connect directly to Agent / Output nodes)",
            "type": "object",
            "x-i18n-key": "nodes.io.input_text.outputs.context",
            "x-port": true
          },
          "json_value": {
            "description": "Parsed result of json_text (null if JSON is invalid)",
            "title": "JSON Value",
            "x-i18n-key": "nodes.io.input_text.outputs.json_value"
          },
          "length": {
            "description": "Character length of the text field (Number)",
            "format": "uint",
            "minimum": 0,
            "title": "Length",
            "type": "integer",
            "x-i18n-key": "nodes.io.input_text.outputs.length"
          },
          "text": {
            "description": "Raw content of the text field (String)",
            "title": "Text",
            "type": "string",
            "x-i18n-key": "nodes.io.input_text.outputs.text"
          }
        },
        "required": [
          "context",
          "length",
          "text"
        ],
        "title": "InputTextOutput",
        "type": "object",
        "x-collapsed-visible": [
          "text",
          "context"
        ],
        "x-field-order": [
          "text",
          "length",
          "json_value",
          "context"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.io.input_text"
    },
    {
      "typeId": "rag/chunker",
      "name": "Document Chunker",
      "category": "rag",
      "description": "Split documents into parent and child chunks, supports structural/fixed/semantic/hybrid modes",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Chunker node input",
        "properties": {
          "child_chunk_chars": {
            "default": null,
            "description": "Child chunk size in characters",
            "title": "Child Chunk Size (chars)",
            "type": "integer",
            "x-allow-custom": true,
            "x-control": "select",
            "x-default": 384,
            "x-i18n-key": "nodes.rag.chunker.inputs.child_chunk_chars",
            "x-options": [
              {
                "label": "128",
                "value": 128
              },
              {
                "label": "256",
                "value": 256
              },
              {
                "label": "384",
                "value": 384
              },
              {
                "label": "512",
                "value": 512
              }
            ]
          },
          "content": {
            "description": "Document text content to chunk",
            "title": "Document Content",
            "type": "string",
            "x-i18n-key": "nodes.rag.chunker.inputs.content"
          },
          "document_id": {
            "default": null,
            "description": "Document identifier (optional, auto-generated if not provided)",
            "title": "Document ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.rag.chunker.inputs.document_id"
          },
          "max_embedding_chars": {
            "default": null,
            "description": "Maximum embedding chunk size - HARD SAFETY LIMIT",
            "title": "Max Embedding Chars",
            "type": "integer",
            "x-allow-custom": true,
            "x-control": "select",
            "x-default": 512,
            "x-i18n-key": "nodes.rag.chunker.inputs.max_embedding_chars",
            "x-options": [
              {
                "label": "512",
                "value": 512
              },
              {
                "label": "1024",
                "value": 1024
              },
              {
                "label": "2048",
                "value": 2048
              },
              {
                "label": "4096",
                "value": 4096
              },
              {
                "label": "8192",
                "value": 8192
              }
            ]
          },
          "mode": {
            "default": null,
            "description": "Select document chunking method",
            "title": "Chunking Mode",
            "type": "string",
            "x-control": "select",
            "x-default": "structural",
            "x-i18n-key": "nodes.rag.chunker.inputs.mode",
            "x-options": [
              {
                "description": "Split by markdown headings",
                "label": "Structural",
                "value": "structural"
              },
              {
                "description": "Split by fixed token length",
                "label": "Fixed Length",
                "value": "fixed"
              },
              {
                "description": "Split by paragraph semantic boundaries",
                "label": "Semantic",
                "value": "semantic"
              },
              {
                "description": "Structural + semantic hybrid",
                "label": "Hybrid",
                "value": "hybrid"
              }
            ]
          },
          "parent_chunk_chars": {
            "default": null,
            "description": "Parent chunk size in characters",
            "title": "Parent Chunk Size (chars)",
            "type": "integer",
            "x-allow-custom": true,
            "x-control": "select",
            "x-default": 384,
            "x-i18n-key": "nodes.rag.chunker.inputs.parent_chunk_chars",
            "x-options": [
              {
                "label": "256",
                "value": 256
              },
              {
                "label": "384",
                "value": 384
              },
              {
                "label": "512",
                "value": 512
              },
              {
                "label": "1024",
                "value": 1024
              }
            ]
          }
        },
        "required": [
          "content"
        ],
        "title": "ChunkerInput",
        "type": "object",
        "x-field-order": [
          "content",
          "document_id",
          "mode",
          "parent_chunk_chars",
          "child_chunk_chars",
          "max_embedding_chars"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "ChunkOutput": {
            "description": "Chunk output representation",
            "properties": {
              "chunk_index": {
                "description": "Chunk index",
                "format": "uint",
                "minimum": 0,
                "title": "Chunk Index",
                "type": "integer"
              },
              "id": {
                "description": "Chunk ID",
                "title": "ID",
                "type": "string"
              },
              "is_parent": {
                "description": "Is parent chunk",
                "title": "Is Parent",
                "type": "boolean"
              },
              "parent_id": {
                "description": "Parent ID (for child chunks)",
                "title": "Parent Id",
                "type": [
                  "string",
                  "null"
                ]
              },
              "text": {
                "description": "Chunk text content",
                "title": "Text",
                "type": "string"
              }
            },
            "required": [
              "chunk_index",
              "id",
              "is_parent",
              "text"
            ],
            "type": "object"
          }
        },
        "description": "Chunker node output",
        "properties": {
          "child_chunks": {
            "description": "List of child chunks",
            "items": {
              "$ref": "#/definitions/ChunkOutput"
            },
            "title": "Child Chunks",
            "type": "array",
            "x-i18n-key": "nodes.rag.chunker.outputs.child_chunks"
          },
          "child_count": {
            "description": "Total child chunk count",
            "format": "uint",
            "minimum": 0,
            "title": "Child Count",
            "type": "integer",
            "x-i18n-key": "nodes.rag.chunker.outputs.child_count"
          },
          "document_id": {
            "description": "Processed document ID",
            "title": "Document ID",
            "type": "string",
            "x-i18n-key": "nodes.rag.chunker.outputs.document_id"
          },
          "mode": {
            "description": "Chunking mode used",
            "title": "Mode",
            "type": "string",
            "x-i18n-key": "nodes.rag.chunker.outputs.mode"
          },
          "parent_chunks": {
            "description": "List of parent chunks",
            "items": {
              "$ref": "#/definitions/ChunkOutput"
            },
            "title": "Parent Chunks",
            "type": "array",
            "x-i18n-key": "nodes.rag.chunker.outputs.parent_chunks"
          },
          "parent_count": {
            "description": "Total parent chunk count",
            "format": "uint",
            "minimum": 0,
            "title": "Parent Count",
            "type": "integer",
            "x-i18n-key": "nodes.rag.chunker.outputs.parent_count"
          }
        },
        "required": [
          "child_chunks",
          "child_count",
          "document_id",
          "mode",
          "parent_chunks",
          "parent_count"
        ],
        "title": "ChunkerOutput",
        "type": "object",
        "x-collapsed-visible": [
          "parent_chunks",
          "child_chunks"
        ],
        "x-field-order": [
          "document_id",
          "parent_chunks",
          "child_chunks",
          "parent_count",
          "child_count",
          "mode"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.rag.chunker"
    },
    {
      "typeId": "utils/approver",
      "name": "Approval Gate",
      "category": "utils",
      "description": "Pause execution and request user authorization before performing a high-risk action. Supports one-time, session-level, and skip decisions.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "action_name": {
            "description": "Name of the action requiring authorization",
            "title": "Action Name",
            "type": "string",
            "x-i18n-key": "nodes.utils.approver.inputs.action_name"
          },
          "description": {
            "default": null,
            "description": "Human-readable explanation of what the action will do",
            "title": "Description",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.utils.approver.inputs.description"
          },
          "extra_whitelist": {
            "default": null,
            "description": "Extra comma-separated action names to auto-approve in addition to session whitelist",
            "title": "Extra Whitelist Rules",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.utils.approver.inputs.extra_whitelist"
          },
          "param_summary": {
            "default": null,
            "description": "JSON summary of action parameters shown in the approval card",
            "title": "Parameter Summary",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.utils.approver.inputs.param_summary"
          },
          "risk_level": {
            "default": "medium",
            "description": "Assessed risk of the action (low / medium / high / critical)",
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "options": [
              {
                "label": "low",
                "value": "low"
              },
              {
                "label": "medium",
                "value": "medium"
              },
              {
                "label": "high",
                "value": "high"
              },
              {
                "label": "critical",
                "value": "critical"
              }
            ],
            "title": "Risk Level",
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.utils.approver.inputs.risk_level"
          },
          "timeout_secs": {
            "default": 300,
            "description": "Seconds to wait before auto-rejecting if no response (default 300)",
            "format": "uint64",
            "minimum": 0,
            "title": "Approval Timeout (s)",
            "type": "integer",
            "x-i18n-key": "nodes.utils.approver.inputs.timeout_secs"
          }
        },
        "required": [
          "action_name"
        ],
        "title": "ApproverInput",
        "type": "object",
        "x-collapsed-visible": [
          "action_name",
          "risk_level"
        ],
        "x-field-order": [
          "action_name",
          "risk_level",
          "description",
          "param_summary",
          "extra_whitelist",
          "timeout_secs"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "ApprovalOutcome": {
            "description": "Outcome of the approval gate.",
            "oneOf": [
              {
                "description": "User approved the action (or whitelist hit).",
                "enum": [
                  "approved"
                ],
                "type": "string"
              },
              {
                "description": "User rejected the action.",
                "enum": [
                  "rejected"
                ],
                "type": "string"
              },
              {
                "description": "User chose to skip this action and return feedback.",
                "enum": [
                  "skipped"
                ],
                "type": "string"
              },
              {
                "description": "No response was received within the timeout window.",
                "enum": [
                  "timed_out"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "approved": {
            "description": "True when the action is allowed to proceed",
            "title": "Approved",
            "type": "boolean",
            "x-i18n-key": "nodes.utils.approver.outputs.approved"
          },
          "outcome": {
            "allOf": [
              {
                "$ref": "#/definitions/ApprovalOutcome"
              }
            ],
            "description": "Detailed approval outcome",
            "title": "Outcome",
            "x-i18n-key": "nodes.utils.approver.outputs.outcome"
          },
          "reason": {
            "description": "User-provided reason or feedback",
            "title": "Reason",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.utils.approver.outputs.reason"
          },
          "request_id": {
            "description": "UUID identifying this approval request",
            "title": "Request ID",
            "type": "string",
            "x-i18n-key": "nodes.utils.approver.outputs.request_id"
          },
          "scope": {
            "description": "Scope granted by the user",
            "title": "Approval Scope",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.utils.approver.outputs.scope"
          },
          "whitelist_hit": {
            "description": "True if action was auto-approved via whitelist",
            "title": "Whitelist Hit",
            "type": "boolean",
            "x-i18n-key": "nodes.utils.approver.outputs.whitelist_hit"
          }
        },
        "required": [
          "approved",
          "outcome",
          "request_id",
          "whitelist_hit"
        ],
        "title": "ApproverOutput",
        "type": "object",
        "x-collapsed-visible": [
          "action_name",
          "risk_level"
        ],
        "x-field-order": [
          "approved",
          "outcome",
          "whitelist_hit",
          "scope",
          "reason",
          "request_id"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.utils.approver"
    },
    {
      "typeId": "io/read_file",
      "name": "Read File",
      "category": "io",
      "description": "Read file content from disk as plain text, can connect to LLM system_prompt or user_message ports. Useful for injecting reference documents, config files, etc.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "file_path": {
            "description": "Absolute or relative path of the file to read",
            "title": "File Path",
            "type": "string",
            "x-control": "file",
            "x-i18n-key": "nodes.io.read_file.inputs.file_path"
          },
          "max_chars": {
            "default": 100000,
            "description": "Maximum characters to read, excess is truncated with a notice appended. 0 means no limit. Default 100000.",
            "format": "uint",
            "minimum": 0,
            "title": "Max Chars",
            "type": "integer",
            "x-i18n-key": "nodes.io.read_file.inputs.max_chars"
          },
          "prefix": {
            "default": null,
            "description": "Optional prefix prepended to file content, provides context description for LLM",
            "title": "Prefix",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.read_file.inputs.prefix"
          },
          "suffix": {
            "default": null,
            "description": "Optional suffix appended after file content",
            "title": "Suffix",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.read_file.inputs.suffix"
          }
        },
        "required": [
          "file_path"
        ],
        "title": "ReadFileInput",
        "type": "object",
        "x-field-order": [
          "file_path",
          "prefix",
          "suffix",
          "max_chars"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "content": {
            "description": "Plain text content of the file (with prefix/suffix), ready to use",
            "title": "Content",
            "type": "string",
            "x-i18n-key": "nodes.io.read_file.outputs.content"
          },
          "error": {
            "description": "发生错误时的错误信息;成功时为 null",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.read_file.outputs.error"
          },
          "file_path": {
            "description": "Actual absolute path of the read file",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.io.read_file.outputs.file_path"
          },
          "total_bytes": {
            "description": "文件总字节数",
            "format": "uint64",
            "minimum": 0,
            "title": "Total Bytes",
            "type": "integer",
            "x-i18n-key": "nodes.io.read_file.outputs.total_bytes"
          },
          "truncated": {
            "description": "内容是否因 max_chars 被截断",
            "type": "boolean",
            "x-i18n-key": "nodes.io.read_file.outputs.truncated"
          }
        },
        "required": [
          "content",
          "file_path",
          "total_bytes",
          "truncated"
        ],
        "title": "ReadFileOutput",
        "type": "object",
        "x-field-order": [
          "content",
          "file_path",
          "total_bytes",
          "truncated",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.io.read_file"
    },
    {
      "typeId": "utils/condition_router",
      "name": "Condition Router",
      "category": "utils",
      "description": "Route by field conditions: supports operator comparison, dot nested path, Schema hint generation, enhanced fallback metadata",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "输入结构",
        "properties": {
          "branch_fields": {
            "default": [],
            "description": "Branch field list (click + to add; each entry auto-generates a corresponding output port)",
            "items": {
              "properties": {
                "condition_logic": {
                  "default": "and",
                  "description": "Condition combination logic: And (all must match) / Or (any matches). Only used when conditions_json is provided.",
                  "enum": [
                    "and",
                    "or"
                  ],
                  "type": "string",
                  "x-control": "select"
                },
                "conditions_json": {
                  "description": "(Advanced) JSON array of extra conditions: [{\"field_name\":\"x\",\"operator\":\"equals\",\"match_value\":\"y\"},...]. Leave empty to use the single field_name/operator above.",
                  "type": "string"
                },
                "description": {
                  "description": "Field description (used for Schema hint generation)",
                  "type": "string"
                },
                "field_name": {
                  "description": "Field path (supports dot notation for nested fields, e.g. action.name)",
                  "type": "string"
                },
                "match_value": {
                  "description": "Match value (required for Equals/NotEquals/Contains/GreaterThan/LessThan)",
                  "type": "string"
                },
                "operator": {
                  "default": "truthy",
                  "description": "Match operator (default: Truthy)",
                  "enum": [
                    "truthy",
                    "exists",
                    "equals",
                    "not_equals",
                    "contains",
                    "greater_than",
                    "less_than"
                  ],
                  "type": "string",
                  "x-control": "select"
                },
                "output_name": {
                  "description": "Custom output port display name (e.g. 'Has Tools'). Leave empty for default branch_N naming.",
                  "type": "string"
                }
              },
              "type": "object"
            },
            "title": "Branch Fields",
            "type": "array",
            "x-dynamic-array": {
              "allowAdd": true,
              "allowRemove": true,
              "maxPorts": 20,
              "minPorts": 0,
              "portPrefix": "branch"
            },
            "x-i18n-key": "nodes.utils.condition_router.inputs.branch_fields"
          },
          "context": {
            "additionalProperties": true,
            "default": null,
            "description": "Input AgentContext (optional)",
            "title": "Agent Context",
            "type": "object",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.utils.condition_router.inputs.context",
            "x-language": "json",
            "x-port": true,
            "x-rows": 2
          },
          "custom_data": {
            "default": null,
            "description": "Custom JSON data",
            "title": "Custom Data",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.utils.condition_router.inputs.custom_data",
            "x-language": "json",
            "x-rows": 2
          },
          "fallback_mode": {
            "default": "fallback_output",
            "description": "FallbackOutput: route to fallback_out (default). None: skip. Output0: route to first branch port.",
            "oneOf": [
              {
                "description": "输出到 fallback_out 端口(默认)",
                "enum": [
                  "fallback_output"
                ],
                "type": "string"
              },
              {
                "description": "不输出,下游自动跳过",
                "enum": [
                  "none"
                ],
                "type": "string"
              },
              {
                "description": "输出到第一个分支端口",
                "enum": [
                  "output0"
                ],
                "type": "string"
              }
            ],
            "title": "Fallback Mode",
            "x-control": "select",
            "x-i18n-key": "nodes.utils.condition_router.inputs.fallback_mode"
          },
          "generate_schema": {
            "default": false,
            "description": "Enable auto-generated JSON Schema hint output to schema_hint port (can connect to upstream LLM's system_prompt)",
            "title": "Generate Schema",
            "type": "boolean",
            "x-i18n-key": "nodes.utils.condition_router.inputs.generate_schema"
          },
          "match_policy": {
            "default": "all",
            "description": "First: stop at first match. All: output all matched branches (default)",
            "oneOf": [
              {
                "description": "仅输出第一个命中的分支",
                "enum": [
                  "first"
                ],
                "type": "string"
              },
              {
                "description": "所有命中的分支都输出(默认)",
                "enum": [
                  "all"
                ],
                "type": "string"
              }
            ],
            "title": "Match Policy",
            "x-control": "select",
            "x-i18n-key": "nodes.utils.condition_router.inputs.match_policy"
          },
          "mode": {
            "default": "advanced",
            "description": "Simple (If: one rule, True/False) or Advanced (Switch: multi-rule, multi-output)",
            "oneOf": [
              {
                "description": "If 模式:单条件,True / False 输出",
                "enum": [
                  "simple"
                ],
                "type": "string"
              },
              {
                "description": "Switch 模式:多规则多输出(默认,兼容旧行为)",
                "enum": [
                  "advanced"
                ],
                "type": "string"
              }
            ],
            "title": "Mode",
            "x-control": "select",
            "x-i18n-key": "nodes.utils.condition_router.inputs.mode"
          },
          "payload_source": {
            "default": "response",
            "description": "Select data extraction source",
            "oneOf": [
              {
                "description": "从 response 字段解析 JSON",
                "enum": [
                  "response"
                ],
                "type": "string"
              },
              {
                "description": "从完整 context 序列化为 JSON",
                "enum": [
                  "context"
                ],
                "type": "string"
              },
              {
                "description": "从 custom_data 字段取值",
                "enum": [
                  "custom"
                ],
                "type": "string"
              }
            ],
            "title": "Payload Source",
            "x-control": "select",
            "x-i18n-key": "nodes.utils.condition_router.inputs.payload_source"
          },
          "response": {
            "default": "",
            "description": "LLM response text (JSON format)",
            "maxLength": 200000,
            "title": "Response",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.utils.condition_router.inputs.response",
            "x-language": "json",
            "x-rows": 2
          },
          "strict_mode": {
            "default": false,
            "description": "Error on JSON parse failure (false routes error reason to fallback output)",
            "title": "Strict Mode",
            "type": "boolean",
            "x-i18n-key": "nodes.utils.condition_router.inputs.strict_mode"
          }
        },
        "title": "ConditionRouterInput",
        "type": "object",
        "x-collapsed-visible": [
          "response",
          "branch_fields"
        ],
        "x-field-order": [
          "context",
          "response",
          "custom_data",
          "payload_source",
          "branch_fields",
          "strict_mode",
          "generate_schema",
          "mode",
          "match_policy",
          "fallback_mode"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AgentContext": {
            "description": "Agent execution context.\n\nContains agent-specific information such as conversation history, iteration count, session tracking, and custom metadata.\n\n# Metadata Conventions\n\nThe `session_id` field is a first-class field for session tracking: - **Initialization**: Should be set by the workflow engine or the first agent node - **Persistence**: Memory nodes (redis/postgres/window) use it for storage keys - **Logging**: LLM and memory nodes include it in tracing logs for debugging - **Propagation**: All nodes should preserve the session_id across the execution chain\n\nAdditional metadata can be stored in the `metadata` HashMap for custom use cases.\n\n# Examples\n\n``` use cheng_nodes::nodes::builtin::agent::base::context::AgentContext; use cheng_llm::types::ChatMessage;\n\nlet context = AgentContext::new() .with_session_id(\"user123_conversation_456\") .with_history(vec![ChatMessage::user(\"Hello\")]) .with_max_iterations(5); ```",
            "properties": {
              "history": {
                "default": [],
                "description": "Conversation history (messages exchanged so far)",
                "items": {
                  "$ref": "#/definitions/ChatMessage"
                },
                "type": "array"
              },
              "iteration": {
                "default": 0,
                "description": "Current iteration count (for ReAct loops, etc.)",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "max_iterations": {
                "default": 10,
                "description": "Maximum iterations allowed",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "metadata": {
                "additionalProperties": true,
                "default": {},
                "description": "Custom metadata (for extensibility)\n\nUse this for additional context that doesn't fit into standard fields. Examples: user preferences, workflow-specific data, feature flags.",
                "type": "object"
              },
              "preview_content": {
                "description": "预览内容(所有消息合并后的纯文本,供预览节点直接展示)\n\n由合并节点(ContextMergeNode)等聚合节点填写,优先于 history 展示。",
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "default": "session_bb130a1b-24b6-43e6-8dfc-cc80e0e69d1c",
                "description": "Session identifier for tracking conversations across nodes and storage\n\nThis should be a unique identifier for the conversation session. Format examples: \"user123_session456\", \"uuid-v4\", \"workflow_exec_789\"",
                "type": "string"
              }
            },
            "type": "object"
          },
          "ChatContentPart": {
            "description": "A single rich content part in a message.\n\nOpenAI Chat Completions accepts either plain text or an array of content parts for user messages. This enum keeps the message model backward compatible while making image/audio/file inputs expressible.",
            "oneOf": [
              {
                "description": "Plain text content.",
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Image input, either a normal URL or a base64 data URL.",
                "properties": {
                  "image_url": {
                    "$ref": "#/definitions/ImageUrlContent"
                  },
                  "type": {
                    "enum": [
                      "image_url"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "image_url",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Audio input for speech recognition / audio reasoning.",
                "properties": {
                  "input_audio": {
                    "$ref": "#/definitions/InputAudioContent"
                  },
                  "type": {
                    "enum": [
                      "input_audio"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "input_audio",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "File input for supported document reasoning models.",
                "properties": {
                  "file": {
                    "$ref": "#/definitions/FileContent"
                  },
                  "type": {
                    "enum": [
                      "file"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "file",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "ChatMessage": {
            "description": "A single message in a conversation.\n\n# Examples\n\n``` use cheng_llm::types::ChatMessage;\n\nlet system_msg = ChatMessage::system(\"You are a helpful assistant.\"); let user_msg = ChatMessage::user(\"What is Rust?\"); let assistant_msg = ChatMessage::assistant(\"Rust is a systems programming language.\"); ```",
            "properties": {
              "content": {
                "type": "string"
              },
              "parts": {
                "description": "Optional rich content parts for multimodal providers.\n\nWhen present, `content` is treated as the leading text prompt and the parts are serialized as the provider-specific content array.",
                "items": {
                  "$ref": "#/definitions/ChatContentPart"
                },
                "type": [
                  "array",
                  "null"
                ]
              },
              "role": {
                "$ref": "#/definitions/Role"
              }
            },
            "required": [
              "content",
              "role"
            ],
            "type": "object"
          },
          "FileContent": {
            "description": "File input payload for OpenAI-style chat content parts.",
            "properties": {
              "file_data": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "file_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "filename": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "ImageUrlContent": {
            "description": "Image input payload for OpenAI-style chat content parts.",
            "properties": {
              "detail": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "url": {
                "type": "string"
              }
            },
            "required": [
              "url"
            ],
            "type": "object"
          },
          "InputAudioContent": {
            "description": "Audio input payload for OpenAI-style chat content parts.",
            "properties": {
              "data": {
                "type": "string"
              },
              "format": {
                "type": "string"
              }
            },
            "required": [
              "data",
              "format"
            ],
            "type": "object"
          },
          "Role": {
            "description": "Message role in a conversation.",
            "enum": [
              "system",
              "user",
              "assistant"
            ],
            "type": "string"
          }
        },
        "description": "输出结构",
        "properties": {
          "branch_outputs": {
            "description": "Branch output list, corresponding 1:1 with branch_fields (AgentContext on match, null on miss)",
            "title": "Branch Outputs",
            "type": "array",
            "x-i18n-key": "nodes.utils.condition_router.outputs.branch_outputs",
            "x-port": true
          },
          "context_out": {
            "anyOf": [
              {
                "$ref": "#/definitions/AgentContext"
              },
              {
                "type": "null"
              }
            ],
            "description": "Legacy fallback output (use fallback_out instead). Mirrors fallback_out for backward compatibility.",
            "title": "Context Out (Legacy)",
            "x-i18n-key": "nodes.utils.condition_router.outputs.context_out",
            "x-runtime-conditional": true
          },
          "fallback_out": {
            "anyOf": [
              {
                "$ref": "#/definitions/AgentContext"
              },
              {
                "type": "null"
              }
            ],
            "description": "Fallback output (acts as 'False' in Simple mode). Fires when no branch rule matches. Includes diagnostic metadata.",
            "title": "Fallback Out",
            "x-i18n-key": "nodes.utils.condition_router.outputs.fallback_out",
            "x-runtime-conditional": true
          },
          "schema_hint": {
            "additionalProperties": true,
            "description": "Auto-generated structured output hint (can connect to upstream LLM node's system_prompt port)",
            "title": "JSON Schema",
            "type": "object",
            "x-i18n-key": "nodes.utils.condition_router.outputs.schema_hint",
            "x-port": true
          }
        },
        "required": [
          "branch_outputs",
          "context_out",
          "fallback_out",
          "schema_hint"
        ],
        "title": "ConditionRouterOutput",
        "type": "object",
        "x-collapsed-visible": [
          "fallback_out",
          "context_out",
          "branch_outputs"
        ],
        "x-field-order": [
          "branch_outputs",
          "fallback_out",
          "context_out",
          "schema_hint"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.utils.condition_router"
    },
    {
      "typeId": "rag/retriever",
      "name": "Knowledge Retriever",
      "category": "rag",
      "description": "Retrieve relevant documents from vector database (economy/power/ultimate modes)",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Retriever node input",
        "properties": {
          "document_filter": {
            "default": null,
            "description": "List of document IDs to limit retrieval scope (optional)",
            "items": {
              "type": "string"
            },
            "title": "Document Filter",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.rag.retriever.inputs.document_filter"
          },
          "embedding_config": {
            "additionalProperties": true,
            "description": "Embedding configuration object from config node",
            "title": "Embedding Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.rag.retriever.inputs.embedding_config",
            "x-port": true
          },
          "kb_id": {
            "description": "Target knowledge base (collection resolved from DB, workspace-validated)",
            "title": "Knowledge Base",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces/{workspace_id}/knowledge-bases?limit=200",
            "x-control": "dynamic-select",
            "x-depends-on": "workspace_id",
            "x-i18n-key": "nodes.rag.retriever.inputs.kb_id"
          },
          "limit": {
            "default": null,
            "description": "Maximum number of results to return",
            "format": "uint",
            "minimum": 0,
            "title": "Result Limit",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.rag.retriever.inputs.limit"
          },
          "llm_config": {
            "additionalProperties": true,
            "default": null,
            "description": "LLM configuration object from config node (optional, for HyDE)",
            "title": "LLM Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.rag.retriever.inputs.llm_config",
            "x-port": true
          },
          "qdrant_config": {
            "additionalProperties": true,
            "description": "Qdrant configuration object from config node",
            "title": "Qdrant Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.rag.retriever.inputs.qdrant_config",
            "x-port": true
          },
          "query": {
            "description": "Query text for retrieval (accepts string or ChatContext)",
            "title": "Query Text",
            "type": "string",
            "x-i18n-key": "nodes.rag.retriever.inputs.query"
          },
          "retrieval_mode": {
            "default": null,
            "description": "Select retrieval strategy",
            "title": "Retrieval Mode",
            "type": "string",
            "x-control": "select",
            "x-default": "economy",
            "x-i18n-key": "nodes.rag.retriever.inputs.retrieval_mode",
            "x-options": [
              {
                "description": "BM25 + child_vec (fast, low cost)",
                "label": "Economy",
                "value": "economy"
              },
              {
                "description": "Parent pre-filter + child_vec + BM25 + RRF (balanced)",
                "label": "Power",
                "value": "power"
              },
              {
                "description": "HyDE + Contextual + Reranker (best quality)",
                "label": "Ultimate",
                "value": "ultimate"
              }
            ]
          },
          "workspace_id": {
            "description": "Target workspace (required for permission validation)",
            "title": "Workspace ID",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces?limit=200",
            "x-cache-key": "static_select:/api/v1/workspaces?limit=200",
            "x-control": "dynamic-select",
            "x-i18n-key": "nodes.rag.retriever.inputs.workspace_id"
          }
        },
        "required": [
          "embedding_config",
          "kb_id",
          "qdrant_config",
          "query",
          "workspace_id"
        ],
        "title": "RetrieverInput",
        "type": "object",
        "x-collapsed-visible": [
          "workspace_id",
          "kb_id",
          "qdrant_config",
          "query",
          "embedding_config",
          "llm_config"
        ],
        "x-field-order": [
          "workspace_id",
          "kb_id",
          "qdrant_config",
          "query",
          "retrieval_mode",
          "limit",
          "embedding_config",
          "llm_config",
          "document_filter"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AgentContext": {
            "description": "Agent execution context.\n\nContains agent-specific information such as conversation history, iteration count, session tracking, and custom metadata.\n\n# Metadata Conventions\n\nThe `session_id` field is a first-class field for session tracking: - **Initialization**: Should be set by the workflow engine or the first agent node - **Persistence**: Memory nodes (redis/postgres/window) use it for storage keys - **Logging**: LLM and memory nodes include it in tracing logs for debugging - **Propagation**: All nodes should preserve the session_id across the execution chain\n\nAdditional metadata can be stored in the `metadata` HashMap for custom use cases.\n\n# Examples\n\n``` use cheng_nodes::nodes::builtin::agent::base::context::AgentContext; use cheng_llm::types::ChatMessage;\n\nlet context = AgentContext::new() .with_session_id(\"user123_conversation_456\") .with_history(vec![ChatMessage::user(\"Hello\")]) .with_max_iterations(5); ```",
            "properties": {
              "history": {
                "default": [],
                "description": "Conversation history (messages exchanged so far)",
                "items": {
                  "$ref": "#/definitions/ChatMessage"
                },
                "type": "array"
              },
              "iteration": {
                "default": 0,
                "description": "Current iteration count (for ReAct loops, etc.)",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "max_iterations": {
                "default": 10,
                "description": "Maximum iterations allowed",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "metadata": {
                "additionalProperties": true,
                "default": {},
                "description": "Custom metadata (for extensibility)\n\nUse this for additional context that doesn't fit into standard fields. Examples: user preferences, workflow-specific data, feature flags.",
                "type": "object"
              },
              "preview_content": {
                "description": "预览内容(所有消息合并后的纯文本,供预览节点直接展示)\n\n由合并节点(ContextMergeNode)等聚合节点填写,优先于 history 展示。",
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "default": "session_caa597ed-3b26-4588-befb-5f86b58b43f8",
                "description": "Session identifier for tracking conversations across nodes and storage\n\nThis should be a unique identifier for the conversation session. Format examples: \"user123_session456\", \"uuid-v4\", \"workflow_exec_789\"",
                "type": "string"
              }
            },
            "type": "object"
          },
          "ChatContentPart": {
            "description": "A single rich content part in a message.\n\nOpenAI Chat Completions accepts either plain text or an array of content parts for user messages. This enum keeps the message model backward compatible while making image/audio/file inputs expressible.",
            "oneOf": [
              {
                "description": "Plain text content.",
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Image input, either a normal URL or a base64 data URL.",
                "properties": {
                  "image_url": {
                    "$ref": "#/definitions/ImageUrlContent"
                  },
                  "type": {
                    "enum": [
                      "image_url"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "image_url",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Audio input for speech recognition / audio reasoning.",
                "properties": {
                  "input_audio": {
                    "$ref": "#/definitions/InputAudioContent"
                  },
                  "type": {
                    "enum": [
                      "input_audio"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "input_audio",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "File input for supported document reasoning models.",
                "properties": {
                  "file": {
                    "$ref": "#/definitions/FileContent"
                  },
                  "type": {
                    "enum": [
                      "file"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "file",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "ChatMessage": {
            "description": "A single message in a conversation.\n\n# Examples\n\n``` use cheng_llm::types::ChatMessage;\n\nlet system_msg = ChatMessage::system(\"You are a helpful assistant.\"); let user_msg = ChatMessage::user(\"What is Rust?\"); let assistant_msg = ChatMessage::assistant(\"Rust is a systems programming language.\"); ```",
            "properties": {
              "content": {
                "type": "string"
              },
              "parts": {
                "description": "Optional rich content parts for multimodal providers.\n\nWhen present, `content` is treated as the leading text prompt and the parts are serialized as the provider-specific content array.",
                "items": {
                  "$ref": "#/definitions/ChatContentPart"
                },
                "type": [
                  "array",
                  "null"
                ]
              },
              "role": {
                "$ref": "#/definitions/Role"
              }
            },
            "required": [
              "content",
              "role"
            ],
            "type": "object"
          },
          "FileContent": {
            "description": "File input payload for OpenAI-style chat content parts.",
            "properties": {
              "file_data": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "file_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "filename": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "ImageUrlContent": {
            "description": "Image input payload for OpenAI-style chat content parts.",
            "properties": {
              "detail": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "url": {
                "type": "string"
              }
            },
            "required": [
              "url"
            ],
            "type": "object"
          },
          "InputAudioContent": {
            "description": "Audio input payload for OpenAI-style chat content parts.",
            "properties": {
              "data": {
                "type": "string"
              },
              "format": {
                "type": "string"
              }
            },
            "required": [
              "data",
              "format"
            ],
            "type": "object"
          },
          "RetrievedDocOutput": {
            "description": "Retrieved document in output",
            "properties": {
              "chunk_index": {
                "description": "Chunk index",
                "format": "int64",
                "title": "Chunk Index",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "context": {
                "description": "Context description (if available)",
                "type": [
                  "string",
                  "null"
                ]
              },
              "document_id": {
                "description": "Parent document ID",
                "title": "Document Id",
                "type": [
                  "string",
                  "null"
                ]
              },
              "id": {
                "description": "Document chunk ID",
                "type": "string"
              },
              "retrieval_method": {
                "description": "Retrieval method used",
                "title": "Retrieval Method",
                "type": [
                  "string",
                  "null"
                ]
              },
              "score": {
                "description": "Relevance score",
                "format": "float",
                "type": "number"
              },
              "text": {
                "description": "Chunk text content",
                "type": "string"
              }
            },
            "required": [
              "id",
              "score",
              "text"
            ],
            "type": "object"
          },
          "Role": {
            "description": "Message role in a conversation.",
            "enum": [
              "system",
              "user",
              "assistant"
            ],
            "type": "string"
          },
          "TokenUsageOutput": {
            "description": "Token usage output",
            "properties": {
              "embedding_tokens": {
                "description": "Embedding tokens",
                "format": "uint32",
                "minimum": 0,
                "title": "Embedding Tokens",
                "type": "integer"
              },
              "hyde_tokens": {
                "description": "HyDE tokens (if used)",
                "format": "uint32",
                "minimum": 0,
                "title": "Hyde Tokens",
                "type": "integer"
              },
              "reranker_tokens": {
                "description": "Reranker tokens (if used)",
                "format": "uint32",
                "minimum": 0,
                "title": "Reranker Tokens",
                "type": "integer"
              },
              "total_tokens": {
                "description": "Total tokens",
                "format": "uint32",
                "minimum": 0,
                "title": "Total Tokens",
                "type": "integer"
              }
            },
            "required": [
              "embedding_tokens",
              "hyde_tokens",
              "reranker_tokens",
              "total_tokens"
            ],
            "type": "object"
          }
        },
        "description": "Retriever node output",
        "properties": {
          "collection_name": {
            "description": "Collection name retrieved from",
            "title": "Collection Name",
            "type": "string",
            "x-i18n-key": "nodes.rag.retriever.outputs.collection_name"
          },
          "count": {
            "description": "Number of results returned",
            "format": "uint",
            "minimum": 0,
            "title": "Count",
            "type": "integer",
            "x-i18n-key": "nodes.rag.retriever.outputs.count"
          },
          "documents": {
            "description": "List of retrieved documents",
            "items": {
              "$ref": "#/definitions/RetrievedDocOutput"
            },
            "title": "Documents",
            "type": "array",
            "x-i18n-key": "nodes.rag.retriever.outputs.documents"
          },
          "has_results": {
            "description": "True when at least one document was retrieved",
            "title": "Has Results",
            "type": "boolean",
            "x-i18n-key": "nodes.rag.retriever.outputs.has_results"
          },
          "latency_ms": {
            "description": "Retrieval latency in milliseconds",
            "format": "uint64",
            "minimum": 0,
            "title": "Latency Ms",
            "type": "integer",
            "x-i18n-key": "nodes.rag.retriever.outputs.latency_ms"
          },
          "query": {
            "description": "Query text used for retrieval",
            "title": "Query",
            "type": "string",
            "x-i18n-key": "nodes.rag.retriever.outputs.query"
          },
          "retrieval_mode": {
            "description": "Retrieval mode used",
            "title": "Retrieval Mode",
            "type": "string",
            "x-i18n-key": "nodes.rag.retriever.outputs.retrieval_mode"
          },
          "summary_input": {
            "anyOf": [
              {
                "$ref": "#/definitions/AgentContext"
              },
              {
                "type": "null"
              }
            ],
            "description": "Lean AgentContext for downstream LLM summarization (conditional: absent when no results)",
            "title": "Summary Input",
            "x-i18n-key": "nodes.rag.retriever.outputs.summary_input",
            "x-runtime-conditional": true
          },
          "token_usage": {
            "allOf": [
              {
                "$ref": "#/definitions/TokenUsageOutput"
              }
            ],
            "description": "Estimated token usage",
            "title": "Token Usage",
            "x-i18n-key": "nodes.rag.retriever.outputs.token_usage"
          }
        },
        "required": [
          "collection_name",
          "count",
          "documents",
          "has_results",
          "latency_ms",
          "query",
          "retrieval_mode",
          "token_usage"
        ],
        "title": "RetrieverOutput",
        "type": "object",
        "x-collapsed-visible": [
          "query",
          "documents",
          "has_results",
          "summary_input"
        ],
        "x-field-order": [
          "documents",
          "count",
          "retrieval_mode",
          "query",
          "latency_ms",
          "collection_name",
          "token_usage",
          "has_results",
          "summary_input"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.rag.retriever"
    },
    {
      "typeId": "workspace/knowledge_base",
      "name": "Knowledge Base",
      "category": "workspace",
      "description": "Select, list, or create knowledge bases in a workspace",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "description": {
            "default": null,
            "description": "Knowledge base description (create mode, optional)",
            "title": "Description",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.knowledge_base.inputs.description"
          },
          "embedding_model": {
            "default": null,
            "description": "Embedding model name (create mode, optional)",
            "title": "Embedding Model",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.knowledge_base.inputs.embedding_model"
          },
          "kb_id": {
            "default": null,
            "description": "Knowledge base to select (select mode)",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces/{workspace_id}/knowledge-bases?limit=200",
            "x-control": "dynamic-select",
            "x-depends-on": "workspace_id",
            "x-i18n-key": "nodes.workspace.knowledge_base.inputs.kb_id"
          },
          "mode": {
            "default": "select",
            "description": "select: Select existing KB; list: List all KBs in workspace; create: Create new KB",
            "enum": [
              "select",
              "list",
              "create"
            ],
            "options": [
              {
                "label": "select",
                "value": "select"
              },
              {
                "label": "list",
                "value": "list"
              },
              {
                "label": "create",
                "value": "create"
              }
            ],
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.workspace.knowledge_base.inputs.mode"
          },
          "name": {
            "default": null,
            "description": "New knowledge base name (create mode)",
            "title": "Name",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.knowledge_base.inputs.name"
          },
          "workspace_id": {
            "description": "Target workspace",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces?limit=200",
            "x-cache-key": "static_select:/api/v1/workspaces?limit=200",
            "x-control": "dynamic-select",
            "x-i18n-key": "nodes.workspace.knowledge_base.inputs.workspace_id"
          }
        },
        "required": [
          "workspace_id"
        ],
        "title": "KnowledgeBaseNodeInput",
        "type": "object",
        "x-field-order": [
          "mode",
          "workspace_id",
          "kb_id",
          "name",
          "description",
          "embedding_model"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "KnowledgeBaseInfo": {
            "properties": {
              "collection_name": {
                "type": "string"
              },
              "document_count": {
                "format": "int64",
                "type": "integer"
              },
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "workspace_id": {
                "type": "string"
              }
            },
            "required": [
              "collection_name",
              "document_count",
              "id",
              "name",
              "status",
              "workspace_id"
            ],
            "type": "object"
          }
        },
        "properties": {
          "error": {
            "description": "Error message if the operation failed.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.knowledge_base.outputs.error"
          },
          "kb_id": {
            "description": "Knowledge base ID (for direct connection)",
            "title": "Knowledge Base ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.knowledge_base.outputs.kb_id"
          },
          "knowledge_base": {
            "anyOf": [
              {
                "$ref": "#/definitions/KnowledgeBaseInfo"
              },
              {
                "type": "null"
              }
            ],
            "description": "Single knowledge base info (select/create modes).",
            "title": "Knowledge Base",
            "x-i18n-key": "nodes.workspace.knowledge_base.outputs.knowledge_base"
          },
          "knowledge_bases": {
            "description": "List of knowledge bases (list mode).",
            "items": {
              "$ref": "#/definitions/KnowledgeBaseInfo"
            },
            "title": "Knowledge Bases",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.knowledge_base.outputs.knowledge_bases"
          },
          "success": {
            "description": "Whether the operation succeeded.",
            "type": "boolean",
            "x-i18n-key": "nodes.workspace.knowledge_base.outputs.success"
          },
          "workspace_id": {
            "description": "Workspace ID (for direct connection)",
            "title": "Workspace ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.knowledge_base.outputs.workspace_id"
          }
        },
        "required": [
          "success"
        ],
        "title": "KnowledgeBaseNodeOutput",
        "type": "object",
        "x-collapsed-visible": [
          "success",
          "knowledge_base",
          "error"
        ],
        "x-field-order": [
          "success",
          "workspace_id",
          "kb_id",
          "knowledge_base",
          "knowledge_bases",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.workspace.knowledge_base"
    },
    {
      "typeId": "io/speech_to_text",
      "name": "Speech To Text",
      "category": "io",
      "description": "Transcribe audio files to text using OpenAI Whisper API, supports mp3/wav/m4a/ogg/flac/webm formats. Accepts local file path or Base64 content input.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "base64_content": {
            "default": null,
            "description": "Base64 encoded audio file content (mutually exclusive with file_path)",
            "title": "Base64 Content",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.io.speech_to_text.inputs.base64_content"
          },
          "file_path": {
            "default": null,
            "description": "Local absolute path of the audio file on server (mutually exclusive with base64_content)",
            "title": "File Path",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.speech_to_text.inputs.file_path"
          },
          "filename": {
            "default": null,
            "description": "Filename, required when using base64_content (e.g. audio.mp3)",
            "title": "Filename",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.speech_to_text.inputs.filename"
          },
          "language": {
            "default": null,
            "description": "Audio language (ISO-639-1, e.g. zh, en), leave empty for auto-detection",
            "title": "Language",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.speech_to_text.inputs.language"
          },
          "llm_config": {
            "additionalProperties": true,
            "description": "LLM config (connect to LLM config node for API Key, Endpoint and model)",
            "title": "LLM Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.io.speech_to_text.inputs.llm_config",
            "x-port": true
          },
          "prompt": {
            "default": null,
            "description": "Prompt (optional), helps model recognize specific terms or speaking style",
            "title": "Prompt",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.io.speech_to_text.inputs.prompt"
          },
          "response_format": {
            "default": "text",
            "description": "Output format: text (plain text) / json / verbose_json / srt / vtt",
            "oneOf": [
              {
                "description": "仅返回纯文本转录",
                "enum": [
                  "text"
                ],
                "type": "string"
              },
              {
                "description": "返回 JSON(含 segments、duration 等)",
                "enum": [
                  "json"
                ],
                "type": "string"
              },
              {
                "description": "返回带时间戳的详细 JSON",
                "enum": [
                  "verbosejson"
                ],
                "type": "string"
              },
              {
                "description": "SubRip 字幕格式",
                "enum": [
                  "srt"
                ],
                "type": "string"
              },
              {
                "description": "WebVTT 字幕格式",
                "enum": [
                  "vtt"
                ],
                "type": "string"
              }
            ],
            "title": "Response Format",
            "x-control": "select",
            "x-i18n-key": "nodes.io.speech_to_text.inputs.response_format"
          },
          "temperature": {
            "default": 0,
            "description": "Sampling temperature 0.0~1.0, 0 means most deterministic output",
            "format": "float",
            "title": "Temperature",
            "type": "number",
            "x-i18n-key": "nodes.io.speech_to_text.inputs.temperature"
          }
        },
        "required": [
          "llm_config"
        ],
        "title": "SpeechToTextInput",
        "type": "object",
        "x-collapsed-visible": [
          "base64_content",
          "filename"
        ],
        "x-field-order": [
          "llm_config",
          "file_path",
          "base64_content",
          "filename",
          "language",
          "prompt",
          "response_format",
          "temperature"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "char_count": {
            "description": "Character count of the transcribed text",
            "format": "uint",
            "minimum": 0,
            "title": "Char Count",
            "type": "integer",
            "x-i18n-key": "nodes.io.speech_to_text.outputs.char_count"
          },
          "detected_language": {
            "description": "Detected language code (only available in verbose_json format)",
            "title": "Detected Language",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.speech_to_text.outputs.detected_language"
          },
          "duration_seconds": {
            "description": "Audio duration in seconds (only available in verbose_json format)",
            "format": "double",
            "title": "Duration Seconds",
            "type": [
              "number",
              "null"
            ],
            "x-i18n-key": "nodes.io.speech_to_text.outputs.duration_seconds"
          },
          "text": {
            "description": "Transcribed text content",
            "title": "Text",
            "type": "string",
            "x-i18n-key": "nodes.io.speech_to_text.outputs.text"
          }
        },
        "required": [
          "char_count",
          "text"
        ],
        "title": "SpeechToTextOutput",
        "type": "object",
        "x-collapsed-visible": [
          "text"
        ],
        "x-field-order": [
          "text",
          "detected_language",
          "duration_seconds",
          "char_count"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.io.speech_to_text"
    },
    {
      "typeId": "tools/view_file",
      "name": "View File",
      "category": "tools",
      "description": "Read file content within specified line range. Always returns total_lines and eof marker to help LLM perceive file full picture and prevent hallucination. Max 500 lines per request.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "end_line": {
            "description": "End line number (inclusive), default min(start_line+499, total_lines)",
            "format": "uint32",
            "minimum": 0,
            "title": "End Line",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.view_file.inputs.end_line"
          },
          "file_path": {
            "description": "Absolute file path to view",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.view_file.inputs.file_path"
          },
          "start_line": {
            "description": "Start line number (1-indexed), default 1",
            "format": "uint32",
            "minimum": 0,
            "title": "Start Line",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.view_file.inputs.start_line"
          }
        },
        "required": [
          "file_path"
        ],
        "title": "ViewFileInput",
        "type": "object"
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "content": {
            "description": "带行号前缀的文件内容(格式:\"  42\\t内容\")",
            "type": "string",
            "x-i18n-key": "nodes.tools.view_file.outputs.content"
          },
          "encoding": {
            "description": "编码(固定 \"utf-8\")",
            "type": "string",
            "x-i18n-key": "nodes.tools.view_file.outputs.encoding"
          },
          "end_line": {
            "description": "实际结束行",
            "format": "uint32",
            "minimum": 0,
            "title": "End Line",
            "type": "integer",
            "x-i18n-key": "nodes.tools.view_file.outputs.end_line"
          },
          "eof": {
            "description": "是否已到达文件末尾",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.view_file.outputs.eof"
          },
          "error": {
            "description": "错误信息(存在时其他字段为空/零值)",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.view_file.outputs.error"
          },
          "file_path": {
            "description": "canonicalize 后的绝对路径",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.view_file.outputs.file_path"
          },
          "start_line": {
            "description": "实际起始行",
            "format": "uint32",
            "minimum": 0,
            "title": "Start Line",
            "type": "integer",
            "x-i18n-key": "nodes.tools.view_file.outputs.start_line"
          },
          "total_bytes": {
            "description": "文件总字节数",
            "format": "uint64",
            "minimum": 0,
            "title": "Total Bytes",
            "type": "integer",
            "x-i18n-key": "nodes.tools.view_file.outputs.total_bytes"
          },
          "total_lines": {
            "description": "文件总行数",
            "format": "uint32",
            "minimum": 0,
            "title": "Total Lines",
            "type": "integer",
            "x-i18n-key": "nodes.tools.view_file.outputs.total_lines"
          },
          "truncated": {
            "description": "是否因超出 500 行上限而截断",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.view_file.outputs.truncated"
          }
        },
        "required": [
          "content",
          "encoding",
          "end_line",
          "eof",
          "file_path",
          "start_line",
          "total_bytes",
          "total_lines",
          "truncated"
        ],
        "title": "ViewFileOutput",
        "type": "object",
        "x-collapsed-visible": [
          "content"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.view_file"
    },
    {
      "typeId": "table/apply_record_ops",
      "name": "Apply Table Operations",
      "category": "table",
      "description": "Batch apply table record insert, update, delete operations",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "CellValue": {
            "description": "Cell value - tagged enum for storing different data types in record cells.\n\nEach variant corresponds to a column type. Values are stored as JSONB with a discriminator tag for type safety.\n\n# JSON Format\n\n```json { \"type\": \"text\", \"value\": \"Hello World\" } { \"type\": \"number\", \"value\": 42.5 } { \"type\": \"checkbox\", \"value\": true } { \"type\": \"select\", \"value\": \"option_id\" } { \"type\": \"date\", \"value\": \"2026-01-06\" } { \"type\": \"null\" } ```",
            "oneOf": [
              {
                "description": "Empty cell (universal clear).",
                "properties": {
                  "type": {
                    "enum": [
                      "null"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Text value.",
                "properties": {
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  },
                  "value": {
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "value"
                ],
                "type": "object"
              },
              {
                "description": "Numeric value (validated: no NaN/Inf, max 10 decimals).",
                "properties": {
                  "type": {
                    "enum": [
                      "number"
                    ],
                    "type": "string"
                  },
                  "value": {
                    "format": "double",
                    "type": "number"
                  }
                },
                "required": [
                  "type",
                  "value"
                ],
                "type": "object"
              },
              {
                "description": "Boolean checkbox value.",
                "properties": {
                  "type": {
                    "enum": [
                      "checkbox"
                    ],
                    "type": "string"
                  },
                  "value": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "type",
                  "value"
                ],
                "type": "object"
              },
              {
                "description": "Single-select option ID.",
                "properties": {
                  "type": {
                    "enum": [
                      "select"
                    ],
                    "type": "string"
                  },
                  "value": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Date value in YYYY-MM-DD format.",
                "properties": {
                  "type": {
                    "enum": [
                      "date"
                    ],
                    "type": "string"
                  },
                  "value": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "InsertPosition": {
            "description": "Insert position for new records.",
            "oneOf": [
              {
                "description": "Insert at the beginning of the table.",
                "enum": [
                  "first"
                ],
                "type": "string"
              },
              {
                "description": "Insert at the end of the table (default).",
                "enum": [
                  "last"
                ],
                "type": "string"
              },
              {
                "additionalProperties": false,
                "description": "Insert before a specific record.",
                "properties": {
                  "before": {
                    "properties": {
                      "reference_id": {
                        "description": "Reference record ID to insert before.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "reference_id"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "before"
                ],
                "type": "object"
              },
              {
                "additionalProperties": false,
                "description": "Insert after a specific record.",
                "properties": {
                  "after": {
                    "properties": {
                      "reference_id": {
                        "description": "Reference record ID to insert after.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "reference_id"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "after"
                ],
                "type": "object"
              }
            ]
          },
          "RecordOperation": {
            "description": "A single record operation.",
            "oneOf": [
              {
                "description": "Insert a new record.",
                "properties": {
                  "data": {
                    "additionalProperties": {
                      "$ref": "#/definitions/CellValue"
                    },
                    "description": "Record data as column_id -> CellValue.",
                    "type": "object"
                  },
                  "op": {
                    "enum": [
                      "insert"
                    ],
                    "type": "string"
                  },
                  "position": {
                    "anyOf": [
                      {
                        "$ref": "#/definitions/InsertPosition"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null,
                    "description": "Position to insert the record. Defaults to \"last\" (append)."
                  }
                },
                "required": [
                  "data",
                  "op"
                ],
                "type": "object"
              },
              {
                "description": "Update an existing record.",
                "properties": {
                  "data": {
                    "additionalProperties": {
                      "$ref": "#/definitions/CellValue"
                    },
                    "description": "Columns to update (PATCH semantics).",
                    "type": "object"
                  },
                  "id": {
                    "description": "Record ID to update.",
                    "type": "string"
                  },
                  "op": {
                    "enum": [
                      "update"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "id",
                  "op"
                ],
                "type": "object"
              },
              {
                "description": "Delete a record.",
                "properties": {
                  "id": {
                    "description": "Record ID to delete.",
                    "type": "string"
                  },
                  "op": {
                    "enum": [
                      "delete"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "op"
                ],
                "type": "object"
              }
            ]
          }
        },
        "description": "Input for TableApplyRecordOpsNode",
        "properties": {
          "operations": {
            "description": "List of operations to apply.",
            "items": {
              "$ref": "#/definitions/RecordOperation"
            },
            "type": "array",
            "x-i18n-key": "nodes.table.apply_record_ops.inputs.operations"
          },
          "summary": {
            "default": null,
            "description": "Optional summary of changes (for logging/audit).",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.table.apply_record_ops.inputs.summary"
          },
          "table_id": {
            "description": "Table ID to apply operations to.",
            "title": "Table Id",
            "type": "string",
            "x-i18n-key": "nodes.table.apply_record_ops.inputs.table_id"
          }
        },
        "required": [
          "operations",
          "table_id"
        ],
        "title": "TableApplyRecordOpsInput",
        "type": "object",
        "x-field-order": [
          "table_id",
          "operations",
          "summary"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "RecordOpResult": {
            "description": "Result of a single record operation.",
            "properties": {
              "error": {
                "description": "Error message if failed.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "index": {
                "description": "Operation index (0-based).",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "op_type": {
                "description": "Operation type.",
                "type": "string"
              },
              "record_id": {
                "description": "Affected record ID (for insert, this is the new ID).",
                "type": [
                  "string",
                  "null"
                ]
              },
              "success": {
                "description": "Whether this operation succeeded.",
                "type": "boolean"
              }
            },
            "required": [
              "index",
              "op_type",
              "success"
            ],
            "type": "object"
          }
        },
        "description": "Output from TableApplyRecordOpsNode",
        "properties": {
          "error": {
            "description": "Error message if the overall operation failed.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.table.apply_record_ops.outputs.error"
          },
          "records_affected": {
            "description": "Number of records affected.",
            "format": "uint",
            "minimum": 0,
            "title": "Records Affected",
            "type": "integer",
            "x-i18n-key": "nodes.table.apply_record_ops.outputs.records_affected"
          },
          "records_deleted": {
            "description": "Number of records deleted.",
            "format": "uint",
            "minimum": 0,
            "title": "Records Deleted",
            "type": "integer",
            "x-i18n-key": "nodes.table.apply_record_ops.outputs.records_deleted"
          },
          "records_inserted": {
            "description": "Number of records inserted.",
            "format": "uint",
            "minimum": 0,
            "title": "Records Inserted",
            "type": "integer",
            "x-i18n-key": "nodes.table.apply_record_ops.outputs.records_inserted"
          },
          "records_updated": {
            "description": "Number of records updated.",
            "format": "uint",
            "minimum": 0,
            "title": "Records Updated",
            "type": "integer",
            "x-i18n-key": "nodes.table.apply_record_ops.outputs.records_updated"
          },
          "results": {
            "description": "Results for each operation.",
            "items": {
              "$ref": "#/definitions/RecordOpResult"
            },
            "type": "array",
            "x-i18n-key": "nodes.table.apply_record_ops.outputs.results"
          },
          "success": {
            "description": "Whether all operations were successful.",
            "type": "boolean",
            "x-i18n-key": "nodes.table.apply_record_ops.outputs.success"
          },
          "summary": {
            "description": "Summary of changes.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.table.apply_record_ops.outputs.summary"
          },
          "table_id": {
            "description": "Table ID.",
            "title": "Table Id",
            "type": "string",
            "x-i18n-key": "nodes.table.apply_record_ops.outputs.table_id"
          }
        },
        "required": [
          "records_affected",
          "records_deleted",
          "records_inserted",
          "records_updated",
          "results",
          "success",
          "table_id"
        ],
        "title": "TableApplyRecordOpsOutput",
        "type": "object",
        "x-collapsed-visible": [
          "summary"
        ],
        "x-field-order": [
          "success",
          "results",
          "summary",
          "table_id",
          "records_affected",
          "records_inserted",
          "records_updated",
          "records_deleted",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.table.apply_record_ops"
    },
    {
      "typeId": "chat/memory",
      "name": "Chat Memory Node",
      "category": "chat",
      "description": "Manage chat conversation history, supports window strategy and database persistence",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "PersistenceMode": {
            "description": "持久化模式\n\n控制聊天历史的存储方式: - Memory: 内存中管理(默认),历史由前端维护 - Database: 从数据库加载历史,支持持久化",
            "oneOf": [
              {
                "description": "内存模式 - 历史由前端维护,不持久化",
                "enum": [
                  "memory"
                ],
                "type": "string"
              },
              {
                "description": "数据库模式 - 从 MessageRepository 加载历史,追加新消息",
                "enum": [
                  "database"
                ],
                "type": "string"
              }
            ]
          },
          "WindowStrategy": {
            "description": "窗口记忆策略",
            "oneOf": [
              {
                "description": "不应用窗口(保留所有消息)",
                "enum": [
                  "none"
                ],
                "type": "string"
              },
              {
                "description": "截断策略(保留最近 N 条)",
                "enum": [
                  "truncate"
                ],
                "type": "string"
              },
              {
                "description": "总结策略(总结旧消息,保留最近 N 条)",
                "enum": [
                  "summarize"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "Chat 记忆节点输入",
        "properties": {
          "conversation_id": {
            "default": null,
            "description": "Conversation ID, in Database mode loads history from database",
            "title": "Conversation ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.chat.memory.inputs.conversation_id"
          },
          "enabled": {
            "default": false,
            "description": "Enable window memory",
            "title": "Enabled",
            "type": "boolean",
            "x-i18n-key": "nodes.chat.memory.inputs.enabled"
          },
          "persistence_mode": {
            "allOf": [
              {
                "$ref": "#/definitions/PersistenceMode"
              }
            ],
            "default": "memory",
            "description": "Persistence mode: memory or database",
            "title": "Persistence Mode",
            "x-i18n-key": "nodes.chat.memory.inputs.persistence_mode"
          },
          "strategy": {
            "allOf": [
              {
                "$ref": "#/definitions/WindowStrategy"
              }
            ],
            "default": "none",
            "description": "Window processing strategy",
            "title": "Strategy",
            "x-i18n-key": "nodes.chat.memory.inputs.strategy"
          },
          "user_message": {
            "description": "This turn's user input text (from chat/input.user_message)",
            "title": "User Message",
            "type": "string",
            "x-i18n-key": "nodes.chat.memory.inputs.user_message",
            "x-port": true
          },
          "user_message_rich": {
            "additionalProperties": true,
            "default": null,
            "description": "Structured user message with multimodal parts",
            "title": "User Message Rich",
            "type": "object",
            "x-i18n-key": "nodes.chat.memory.inputs.user_message_rich",
            "x-port": true
          },
          "window_size": {
            "default": 50,
            "description": "Maximum messages to retain",
            "format": "uint",
            "minimum": 0,
            "title": "Window Size",
            "type": "integer",
            "x-i18n-key": "nodes.chat.memory.inputs.window_size"
          },
          "workspace_id": {
            "default": null,
            "description": "Workspace ID (UUID string), required when creating new conversation",
            "title": "Workspace ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.chat.memory.inputs.workspace_id"
          }
        },
        "required": [
          "user_message"
        ],
        "title": "ChatMemoryNodeInput",
        "type": "object",
        "x-field-order": [
          "user_message",
          "user_message_rich",
          "window_size",
          "strategy",
          "enabled",
          "persistence_mode",
          "conversation_id",
          "workspace_id"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "ChatContentPart": {
            "description": "A single rich content part in a message.\n\nOpenAI Chat Completions accepts either plain text or an array of content parts for user messages. This enum keeps the message model backward compatible while making image/audio/file inputs expressible.",
            "oneOf": [
              {
                "description": "Plain text content.",
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Image input, either a normal URL or a base64 data URL.",
                "properties": {
                  "image_url": {
                    "$ref": "#/definitions/ImageUrlContent"
                  },
                  "type": {
                    "enum": [
                      "image_url"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "image_url",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Audio input for speech recognition / audio reasoning.",
                "properties": {
                  "input_audio": {
                    "$ref": "#/definitions/InputAudioContent"
                  },
                  "type": {
                    "enum": [
                      "input_audio"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "input_audio",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "File input for supported document reasoning models.",
                "properties": {
                  "file": {
                    "$ref": "#/definitions/FileContent"
                  },
                  "type": {
                    "enum": [
                      "file"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "file",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "ChatMessage": {
            "description": "A single message in a conversation.\n\n# Examples\n\n``` use cheng_llm::types::ChatMessage;\n\nlet system_msg = ChatMessage::system(\"You are a helpful assistant.\"); let user_msg = ChatMessage::user(\"What is Rust?\"); let assistant_msg = ChatMessage::assistant(\"Rust is a systems programming language.\"); ```",
            "properties": {
              "content": {
                "type": "string"
              },
              "parts": {
                "description": "Optional rich content parts for multimodal providers.\n\nWhen present, `content` is treated as the leading text prompt and the parts are serialized as the provider-specific content array.",
                "items": {
                  "$ref": "#/definitions/ChatContentPart"
                },
                "type": [
                  "array",
                  "null"
                ]
              },
              "role": {
                "$ref": "#/definitions/Role"
              }
            },
            "required": [
              "content",
              "role"
            ],
            "type": "object"
          },
          "FileContent": {
            "description": "File input payload for OpenAI-style chat content parts.",
            "properties": {
              "file_data": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "file_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "filename": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "ImageUrlContent": {
            "description": "Image input payload for OpenAI-style chat content parts.",
            "properties": {
              "detail": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "url": {
                "type": "string"
              }
            },
            "required": [
              "url"
            ],
            "type": "object"
          },
          "InputAudioContent": {
            "description": "Audio input payload for OpenAI-style chat content parts.",
            "properties": {
              "data": {
                "type": "string"
              },
              "format": {
                "type": "string"
              }
            },
            "required": [
              "data",
              "format"
            ],
            "type": "object"
          },
          "MemoryStats": {
            "description": "记忆处理统计",
            "properties": {
              "display_count": {
                "description": "显示消息总数",
                "format": "uint",
                "minimum": 0,
                "title": "Display Count",
                "type": "integer"
              },
              "history_count_after": {
                "description": "历史消息总数(处理后)",
                "format": "uint",
                "minimum": 0,
                "title": "History Count After",
                "type": "integer"
              },
              "history_count_before": {
                "description": "历史消息总数(处理前)",
                "format": "uint",
                "minimum": 0,
                "title": "History Count Before",
                "type": "integer"
              },
              "input_count": {
                "description": "输入消息总数",
                "format": "uint",
                "minimum": 0,
                "title": "Input Count",
                "type": "integer"
              },
              "truncated_count": {
                "description": "被截断的消息数",
                "format": "uint",
                "minimum": 0,
                "title": "Truncated Count",
                "type": "integer"
              },
              "window_applied": {
                "description": "是否应用了窗口策略",
                "title": "Window Applied",
                "type": "boolean"
              }
            },
            "required": [
              "display_count",
              "history_count_after",
              "history_count_before",
              "input_count",
              "truncated_count",
              "window_applied"
            ],
            "type": "object"
          },
          "MessagePacket": {
            "description": "消息包 - Chat 系统的核心数据结构",
            "properties": {
              "hash": {
                "description": "Message hash (for deduplication and idempotency)",
                "pattern": "^[0-9a-f]{32}$",
                "title": "Hash",
                "type": "string"
              },
              "id": {
                "description": "Unique message ID",
                "title": "ID",
                "type": "string"
              },
              "meta": {
                "additionalProperties": true,
                "description": "Message metadata",
                "title": "Meta",
                "type": "object"
              },
              "msg_type": {
                "allOf": [
                  {
                    "$ref": "#/definitions/MessageType"
                  }
                ],
                "description": "Message type (text/image/file/audio, etc.)",
                "title": "Msg Type"
              },
              "payload": {
                "description": "Message content payload",
                "title": "Payload"
              },
              "protocol_version": {
                "description": "Protocol version",
                "title": "Protocol Version",
                "type": "string"
              },
              "stream_hint": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/StreamHint"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Stream shard info",
                "title": "Stream Hint"
              },
              "timestamp": {
                "description": "Message creation timestamp (Unix ms)",
                "format": "int64",
                "title": "Timestamp",
                "type": "integer"
              }
            },
            "required": [
              "hash",
              "id",
              "meta",
              "msg_type",
              "payload",
              "protocol_version",
              "timestamp"
            ],
            "type": "object"
          },
          "MessageType": {
            "description": "消息类型",
            "oneOf": [
              {
                "description": "纯文本",
                "enum": [
                  "text"
                ],
                "type": "string"
              },
              {
                "description": "图片",
                "enum": [
                  "image"
                ],
                "type": "string"
              },
              {
                "description": "文件",
                "enum": [
                  "file"
                ],
                "type": "string"
              },
              {
                "description": "音频",
                "enum": [
                  "audio"
                ],
                "type": "string"
              },
              {
                "description": "视频",
                "enum": [
                  "video"
                ],
                "type": "string"
              },
              {
                "description": "OCR 识别结果",
                "enum": [
                  "ocr_text"
                ],
                "type": "string"
              },
              {
                "description": "流式分片",
                "enum": [
                  "stream"
                ],
                "type": "string"
              },
              {
                "description": "控制消息(如清屏、状态变更)",
                "enum": [
                  "control"
                ],
                "type": "string"
              },
              {
                "description": "错误消息",
                "enum": [
                  "error"
                ],
                "type": "string"
              },
              {
                "description": "网页快照",
                "enum": [
                  "web_snapshot"
                ],
                "type": "string"
              },
              {
                "description": "系统消息",
                "enum": [
                  "system"
                ],
                "type": "string"
              }
            ]
          },
          "Role": {
            "description": "Message role in a conversation.",
            "enum": [
              "system",
              "user",
              "assistant"
            ],
            "type": "string"
          },
          "StreamHint": {
            "description": "流式分片提示",
            "properties": {
              "chunk_index": {
                "description": "分片索引(从 0 开始)",
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "group_id": {
                "description": "所属消息组 ID",
                "type": "string"
              },
              "is_final": {
                "description": "是否为最后一个分片",
                "type": "boolean"
              }
            },
            "required": [
              "chunk_index",
              "group_id",
              "is_final"
            ],
            "type": "object"
          }
        },
        "description": "Chat 记忆节点输出",
        "properties": {
          "agent_context": {
            "additionalProperties": true,
            "description": "AgentContext wrapper, connectable to agent/llm or agent/react context port",
            "title": "Agent Context",
            "type": "object",
            "x-i18n-key": "nodes.chat.memory.outputs.agent_context",
            "x-port": true
          },
          "clean_history_json": {
            "description": "Clean history before appending current user message (JSON format), for chat/save_reply",
            "title": "Clean History JSON",
            "type": "string",
            "x-i18n-key": "nodes.chat.memory.outputs.clean_history_json",
            "x-port": true
          },
          "conversation_id": {
            "description": "Current conversation ID (always present, downstream nodes only consume, never recreate)",
            "title": "Conversation ID",
            "type": "string",
            "x-i18n-key": "nodes.chat.memory.outputs.conversation_id",
            "x-port": true
          },
          "display_messages": {
            "description": "Processed message list (for frontend display)",
            "items": {
              "$ref": "#/definitions/MessagePacket"
            },
            "title": "Display Messages",
            "type": "array",
            "x-i18n-key": "nodes.chat.memory.outputs.display_messages"
          },
          "stats": {
            "allOf": [
              {
                "$ref": "#/definitions/MemoryStats"
              }
            ],
            "description": "Processing statistics",
            "title": "Stats",
            "x-i18n-key": "nodes.chat.memory.outputs.stats"
          },
          "updated_history": {
            "description": "Updated complete history messages",
            "items": {
              "$ref": "#/definitions/ChatMessage"
            },
            "title": "Updated History",
            "type": "array",
            "x-i18n-key": "nodes.chat.memory.outputs.updated_history"
          },
          "user_message_rich": {
            "additionalProperties": true,
            "description": "Structured user message for downstream nodes",
            "title": "User Message Rich",
            "type": "object",
            "x-i18n-key": "nodes.chat.memory.outputs.user_message_rich",
            "x-port": true
          }
        },
        "required": [
          "agent_context",
          "clean_history_json",
          "conversation_id",
          "display_messages",
          "stats",
          "updated_history",
          "user_message_rich"
        ],
        "title": "ChatMemoryNodeOutput",
        "type": "object",
        "x-collapsed-visible": [
          "agent_context"
        ],
        "x-field-order": [
          "display_messages",
          "updated_history",
          "user_message_rich",
          "agent_context",
          "conversation_id",
          "clean_history_json",
          "stats"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.chat.memory"
    },
    {
      "typeId": "io/document_to_text",
      "name": "Document To Text",
      "category": "io",
      "description": "Parse PDF, Word, Excel, TXT and other files to plain text, can connect to LLM or RAG nodes. Supports local file path and Base64 content input.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "base64_content": {
            "default": null,
            "description": "Base64 encoded file content (mutually exclusive with file_path)",
            "title": "Base64 Content",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.io.document_to_text.inputs.base64_content"
          },
          "file_path": {
            "default": null,
            "description": "Local absolute file path on server (mutually exclusive with base64_content)",
            "title": "File Path",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.document_to_text.inputs.file_path"
          },
          "filename": {
            "default": null,
            "description": "Filename used to infer format (required when using base64_content)",
            "title": "Filename",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.document_to_text.inputs.filename"
          },
          "max_chars": {
            "default": 0,
            "description": "Maximum characters to extract, 0 means no limit",
            "format": "uint64",
            "minimum": 0,
            "title": "Max Chars",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.document_to_text.inputs.max_chars"
          }
        },
        "title": "DocumentToTextInput",
        "type": "object",
        "x-collapsed-visible": [
          "base64_content",
          "filename"
        ],
        "x-field-order": [
          "file_path",
          "base64_content",
          "filename",
          "max_chars"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "char_count": {
            "description": "Number of characters extracted",
            "format": "uint",
            "minimum": 0,
            "title": "Char Count",
            "type": "integer",
            "x-i18n-key": "nodes.io.document_to_text.outputs.char_count"
          },
          "format": {
            "description": "Detected file format (pdf / docx / xlsx / txt etc.)",
            "title": "Format",
            "type": "string",
            "x-i18n-key": "nodes.io.document_to_text.outputs.format"
          },
          "text": {
            "description": "Extracted plain text content",
            "title": "Text",
            "type": "string",
            "x-i18n-key": "nodes.io.document_to_text.outputs.text"
          },
          "truncated": {
            "description": "Whether content was truncated due to exceeding max_chars",
            "title": "Truncated",
            "type": "boolean",
            "x-i18n-key": "nodes.io.document_to_text.outputs.truncated"
          }
        },
        "required": [
          "char_count",
          "format",
          "text",
          "truncated"
        ],
        "title": "DocumentToTextOutput",
        "type": "object",
        "x-collapsed-visible": [
          "text"
        ],
        "x-field-order": [
          "text",
          "char_count",
          "format",
          "truncated"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.io.document_to_text"
    },
    {
      "typeId": "ai/context_merge",
      "name": "Context Merge",
      "category": "agent",
      "description": "Merge AgentContext from multiple input sources, for passing to LLM or output nodes",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "输入结构",
        "properties": {
          "custom_session_id": {
            "default": null,
            "description": "Custom session_id (optional)",
            "maxLength": 200,
            "title": "Custom Session ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.ai.context_merge.inputs.custom_session_id"
          },
          "extra_inputs": {
            "description": "Extra input sources (click + to add dynamically)",
            "title": "Extra Inputs",
            "type": "array",
            "x-control": "text",
            "x-dynamic-array": {
              "allowAdd": true,
              "allowRemove": true,
              "maxPorts": 20,
              "minPorts": 0,
              "portPrefix": "input"
            },
            "x-i18n-key": "nodes.ai.context_merge.inputs.extra_inputs"
          },
          "input1": {
            "additionalProperties": true,
            "description": "AgentContext input source (connect via port; use JSON format for manual input)",
            "title": "Input 1",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.ai.context_merge.inputs.input1",
            "x-port": true
          },
          "input2": {
            "additionalProperties": true,
            "description": "AgentContext input source (connect via port; use JSON format for manual input)",
            "title": "Input 2",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.ai.context_merge.inputs.input2",
            "x-port": true
          },
          "merge_strategy": {
            "default": "append",
            "description": "Message merge strategy",
            "oneOf": [
              {
                "description": "追加模式:按顺序追加所有消息",
                "enum": [
                  "append"
                ],
                "type": "string"
              },
              {
                "description": "去重模式:相同内容的消息只保留一条",
                "enum": [
                  "deduplicate"
                ],
                "type": "string"
              },
              {
                "description": "最新优先:只保留每个角色的最新消息",
                "enum": [
                  "latest_only"
                ],
                "type": "string"
              }
            ],
            "title": "Merge Strategy",
            "x-control": "select",
            "x-i18n-key": "nodes.ai.context_merge.inputs.merge_strategy"
          },
          "system_message": {
            "default": null,
            "description": "Additional system message (optional)",
            "maxLength": 50000,
            "title": "System Message",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.ai.context_merge.inputs.system_message"
          }
        },
        "title": "ContextMergeInput",
        "type": "object",
        "x-collapsed-visible": [
          "input1",
          "input2"
        ],
        "x-field-order": [
          "input1",
          "input2",
          "extra_inputs",
          "merge_strategy",
          "custom_session_id",
          "system_message"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "MergeStats": {
            "description": "合并统计",
            "properties": {
              "deduplicated": {
                "description": "去重移除的消息数",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "input_count": {
                "description": "输入源数量",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "metadata_keys": {
                "description": "合并的 metadata 键数量",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "total_messages": {
                "description": "合并后的消息总数",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "deduplicated",
              "input_count",
              "metadata_keys",
              "total_messages"
            ],
            "type": "object"
          }
        },
        "description": "输出结构",
        "properties": {
          "context": {
            "additionalProperties": true,
            "description": "AgentContext output port (merged conversation history)",
            "title": "Context",
            "type": "object",
            "x-i18n-key": "nodes.ai.context_merge.outputs.context",
            "x-port": true
          },
          "formatted_content": {
            "description": "Plain text concatenation of all merged messages",
            "title": "Formatted Content",
            "type": "string",
            "x-i18n-key": "nodes.ai.context_merge.outputs.formatted_content"
          },
          "stats": {
            "allOf": [
              {
                "$ref": "#/definitions/MergeStats"
              }
            ],
            "description": "Merge statistics",
            "title": "Stats",
            "x-i18n-key": "nodes.ai.context_merge.outputs.stats"
          }
        },
        "required": [
          "context",
          "formatted_content",
          "stats"
        ],
        "title": "ContextMergeOutput",
        "type": "object",
        "x-collapsed-visible": [
          "context",
          "formatted_content"
        ],
        "x-field-order": [
          "context",
          "formatted_content",
          "stats"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.ai.context_merge"
    },
    {
      "typeId": "document/create",
      "name": "Create Document",
      "category": "document",
      "description": "Create a new document in workspace, supports AgentContext pass-through",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input for DocumentCreateNode",
        "properties": {
          "block_type": {
            "default": "paragraph",
            "description": "Block type for initial content (default: paragraph).",
            "title": "Block Type",
            "type": "string",
            "x-i18n-key": "nodes.document.create.inputs.block_type"
          },
          "context": {
            "additionalProperties": true,
            "default": null,
            "description": "AgentContext port",
            "title": "Context",
            "type": "object",
            "x-i18n-key": "nodes.document.create.inputs.context",
            "x-port": true
          },
          "initial_content": {
            "default": null,
            "description": "Initial content for the first block (optional).",
            "title": "Initial Content",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.create.inputs.initial_content"
          },
          "priority": {
            "default": "normal",
            "description": "Initial block priority",
            "enum": [
              "low",
              "normal",
              "medium",
              "high",
              "critical"
            ],
            "options": [
              {
                "label": "low",
                "value": "low"
              },
              {
                "label": "normal",
                "value": "normal"
              },
              {
                "label": "medium",
                "value": "medium"
              },
              {
                "label": "high",
                "value": "high"
              },
              {
                "label": "critical",
                "value": "critical"
              }
            ],
            "title": "Priority",
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.document.create.inputs.priority"
          },
          "tags": {
            "default": null,
            "description": "Initial block tags (comma-separated)",
            "title": "Tags",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.create.inputs.tags"
          },
          "title": {
            "default": null,
            "description": "Optional title for the document.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.create.inputs.title"
          },
          "workspace_id": {
            "description": "Select workspace to create document in",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces?limit=200",
            "x-cache-key": "static_select:/api/v1/workspaces?limit=200",
            "x-control": "dynamic-select",
            "x-i18n-key": "nodes.document.create.inputs.workspace_id"
          }
        },
        "required": [
          "workspace_id"
        ],
        "title": "DocumentCreateInput",
        "type": "object",
        "x-field-order": [
          "context",
          "workspace_id",
          "title",
          "initial_content",
          "block_type",
          "priority",
          "tags"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Output from DocumentCreateNode",
        "properties": {
          "context": {
            "additionalProperties": true,
            "description": "AgentContext port",
            "title": "Context",
            "type": "object",
            "x-i18n-key": "nodes.document.create.outputs.context",
            "x-port": true
          },
          "document_id": {
            "description": "ID of the created document.",
            "title": "Document Id",
            "type": "string",
            "x-i18n-key": "nodes.document.create.outputs.document_id"
          },
          "error": {
            "description": "Error message if creation failed.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.create.outputs.error"
          },
          "root_block_id": {
            "description": "ID of the root block.",
            "title": "Root Block Id",
            "type": "string",
            "x-i18n-key": "nodes.document.create.outputs.root_block_id"
          },
          "string": {
            "description": "Formatted success message with title and document_id",
            "type": "string",
            "x-i18n-key": "nodes.document.create.outputs.string"
          },
          "success": {
            "description": "Whether creation was successful.",
            "type": "boolean",
            "x-i18n-key": "nodes.document.create.outputs.success"
          },
          "title": {
            "description": "Title of the created document.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.create.outputs.title"
          }
        },
        "required": [
          "context",
          "document_id",
          "root_block_id",
          "string",
          "success"
        ],
        "title": "DocumentCreateOutput",
        "type": "object",
        "x-collapsed-visible": [
          "context",
          "string"
        ],
        "x-field-order": [
          "context",
          "string",
          "document_id",
          "title",
          "root_block_id",
          "success",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.document.create"
    },
    {
      "typeId": "utils/delay",
      "name": "Delay Node",
      "category": "utils",
      "description": "Add delay in workflow, for testing pause and stop functionality",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "delay_unit": {
            "default": "seconds",
            "description": "Delay time unit: milliseconds or seconds",
            "oneOf": [
              {
                "description": "毫秒",
                "enum": [
                  "milliseconds"
                ],
                "type": "string"
              },
              {
                "description": "秒",
                "enum": [
                  "seconds"
                ],
                "type": "string"
              }
            ],
            "title": "Delay Unit",
            "x-control": "select",
            "x-i18n-key": "nodes.utils.delay.inputs.delay_unit"
          },
          "delay_value": {
            "default": 5,
            "description": "Delay time value (used with unit)",
            "format": "uint64",
            "maximum": 3600000,
            "minimum": 0,
            "title": "Delay Value",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.utils.delay.inputs.delay_value"
          },
          "log_message": {
            "default": null,
            "description": "Log message: output before and after delay",
            "title": "Log Message",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.utils.delay.inputs.log_message"
          },
          "passthrough": {
            "default": null,
            "description": "Passthrough data: forwarded as-is to output port",
            "title": "Passthrough",
            "x-i18n-key": "nodes.utils.delay.inputs.passthrough"
          }
        },
        "title": "DelayInput",
        "type": "object",
        "x-collapsed-visible": [
          "delay_value",
          "delay_unit",
          "log_message",
          "passthrough"
        ],
        "x-field-order": [
          "delay_value",
          "delay_unit",
          "log_message",
          "passthrough"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AgentContext": {
            "description": "Agent execution context.\n\nContains agent-specific information such as conversation history, iteration count, session tracking, and custom metadata.\n\n# Metadata Conventions\n\nThe `session_id` field is a first-class field for session tracking: - **Initialization**: Should be set by the workflow engine or the first agent node - **Persistence**: Memory nodes (redis/postgres/window) use it for storage keys - **Logging**: LLM and memory nodes include it in tracing logs for debugging - **Propagation**: All nodes should preserve the session_id across the execution chain\n\nAdditional metadata can be stored in the `metadata` HashMap for custom use cases.\n\n# Examples\n\n``` use cheng_nodes::nodes::builtin::agent::base::context::AgentContext; use cheng_llm::types::ChatMessage;\n\nlet context = AgentContext::new() .with_session_id(\"user123_conversation_456\") .with_history(vec![ChatMessage::user(\"Hello\")]) .with_max_iterations(5); ```",
            "properties": {
              "history": {
                "default": [],
                "description": "Conversation history (messages exchanged so far)",
                "items": {
                  "$ref": "#/definitions/ChatMessage"
                },
                "type": "array"
              },
              "iteration": {
                "default": 0,
                "description": "Current iteration count (for ReAct loops, etc.)",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "max_iterations": {
                "default": 10,
                "description": "Maximum iterations allowed",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "metadata": {
                "additionalProperties": true,
                "default": {},
                "description": "Custom metadata (for extensibility)\n\nUse this for additional context that doesn't fit into standard fields. Examples: user preferences, workflow-specific data, feature flags.",
                "type": "object"
              },
              "preview_content": {
                "description": "预览内容(所有消息合并后的纯文本,供预览节点直接展示)\n\n由合并节点(ContextMergeNode)等聚合节点填写,优先于 history 展示。",
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "default": "session_059cc2ab-8c1a-422e-bfe2-34bb180fb849",
                "description": "Session identifier for tracking conversations across nodes and storage\n\nThis should be a unique identifier for the conversation session. Format examples: \"user123_session456\", \"uuid-v4\", \"workflow_exec_789\"",
                "type": "string"
              }
            },
            "type": "object"
          },
          "ChatContentPart": {
            "description": "A single rich content part in a message.\n\nOpenAI Chat Completions accepts either plain text or an array of content parts for user messages. This enum keeps the message model backward compatible while making image/audio/file inputs expressible.",
            "oneOf": [
              {
                "description": "Plain text content.",
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Image input, either a normal URL or a base64 data URL.",
                "properties": {
                  "image_url": {
                    "$ref": "#/definitions/ImageUrlContent"
                  },
                  "type": {
                    "enum": [
                      "image_url"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "image_url",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Audio input for speech recognition / audio reasoning.",
                "properties": {
                  "input_audio": {
                    "$ref": "#/definitions/InputAudioContent"
                  },
                  "type": {
                    "enum": [
                      "input_audio"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "input_audio",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "File input for supported document reasoning models.",
                "properties": {
                  "file": {
                    "$ref": "#/definitions/FileContent"
                  },
                  "type": {
                    "enum": [
                      "file"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "file",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "ChatMessage": {
            "description": "A single message in a conversation.\n\n# Examples\n\n``` use cheng_llm::types::ChatMessage;\n\nlet system_msg = ChatMessage::system(\"You are a helpful assistant.\"); let user_msg = ChatMessage::user(\"What is Rust?\"); let assistant_msg = ChatMessage::assistant(\"Rust is a systems programming language.\"); ```",
            "properties": {
              "content": {
                "type": "string"
              },
              "parts": {
                "description": "Optional rich content parts for multimodal providers.\n\nWhen present, `content` is treated as the leading text prompt and the parts are serialized as the provider-specific content array.",
                "items": {
                  "$ref": "#/definitions/ChatContentPart"
                },
                "type": [
                  "array",
                  "null"
                ]
              },
              "role": {
                "$ref": "#/definitions/Role"
              }
            },
            "required": [
              "content",
              "role"
            ],
            "type": "object"
          },
          "DelayInfo": {
            "properties": {
              "end_timestamp_ms": {
                "description": "结束时间戳(Unix 毫秒)",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "log_message": {
                "description": "日志消息(如果有)",
                "type": [
                  "string",
                  "null"
                ]
              },
              "requested_unit": {
                "description": "请求的延迟时间单位",
                "type": "string"
              },
              "requested_value": {
                "description": "请求的延迟时间值",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "start_timestamp_ms": {
                "description": "开始时间戳(Unix 毫秒)",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "end_timestamp_ms",
              "requested_unit",
              "requested_value",
              "start_timestamp_ms"
            ],
            "type": "object"
          },
          "FileContent": {
            "description": "File input payload for OpenAI-style chat content parts.",
            "properties": {
              "file_data": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "file_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "filename": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "ImageUrlContent": {
            "description": "Image input payload for OpenAI-style chat content parts.",
            "properties": {
              "detail": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "url": {
                "type": "string"
              }
            },
            "required": [
              "url"
            ],
            "type": "object"
          },
          "InputAudioContent": {
            "description": "Audio input payload for OpenAI-style chat content parts.",
            "properties": {
              "data": {
                "type": "string"
              },
              "format": {
                "type": "string"
              }
            },
            "required": [
              "data",
              "format"
            ],
            "type": "object"
          },
          "Role": {
            "description": "Message role in a conversation.",
            "enum": [
              "system",
              "user",
              "assistant"
            ],
            "type": "string"
          }
        },
        "properties": {
          "actual_delay_ms": {
            "description": "Actual delay duration (milliseconds)",
            "format": "uint64",
            "minimum": 0,
            "title": "Actual Delay Ms",
            "type": "integer",
            "x-i18n-key": "nodes.utils.delay.outputs.actual_delay_ms"
          },
          "completed": {
            "description": "Whether delay completed normally",
            "title": "Completed",
            "type": "boolean",
            "x-i18n-key": "nodes.utils.delay.outputs.completed"
          },
          "context": {
            "allOf": [
              {
                "$ref": "#/definitions/AgentContext"
              }
            ],
            "description": "AgentContext combining log_message and passthrough",
            "title": "Context",
            "x-i18n-key": "nodes.utils.delay.outputs.context"
          },
          "info": {
            "allOf": [
              {
                "$ref": "#/definitions/DelayInfo"
              }
            ],
            "description": "Detailed delay execution info",
            "title": "Info",
            "x-i18n-key": "nodes.utils.delay.outputs.info"
          },
          "log_message": {
            "description": "Passthrough log message from input",
            "title": "Log Message",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.utils.delay.outputs.log_message"
          },
          "passthrough": {
            "description": "Passthrough data from input",
            "title": "Passthrough",
            "x-i18n-key": "nodes.utils.delay.outputs.passthrough"
          }
        },
        "required": [
          "actual_delay_ms",
          "completed",
          "context",
          "info"
        ],
        "title": "DelayOutput",
        "type": "object",
        "x-collapsed-visible": [
          "log_message",
          "context",
          "passthrough"
        ],
        "x-field-order": [
          "completed",
          "actual_delay_ms",
          "passthrough",
          "log_message",
          "context",
          "info"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.utils.delay"
    },
    {
      "typeId": "utils/credential",
      "name": "Credential Injection",
      "category": "utils",
      "description": "Load saved credentials and expose them as env vars for downstream nodes. Supports provider auto-match, provider/name selection, and legacy UUID refs.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input for the Credential Injection node.\n\nEach entry in `bindings` maps an environment variable name to a credential reference. See the module documentation for supported reference formats.",
        "properties": {
          "bindings": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Map each env var name to a credential ref. Ref supports `provider` (auto-select), `provider/name` (pick one), or UUID (legacy). Example: {\"OPENAI_API_KEY\":\"openai\", \"GITHUB_TOKEN\":\"github/work\"}",
            "title": "Bindings",
            "type": "object",
            "x-i18n-key": "nodes.utils.credential.inputs.bindings"
          },
          "context_name": {
            "default": null,
            "description": "Context label shown in log and error messages.",
            "title": "Context Name",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.utils.credential.inputs.context_name"
          },
          "strict": {
            "default": true,
            "description": "When enabled, any missing credential stops the node. When disabled, returns resolved env vars and lists failed keys in `missing_bindings`.",
            "title": "Strict Mode",
            "type": "boolean",
            "x-i18n-key": "nodes.utils.credential.inputs.strict"
          },
          "user_id": {
            "default": null,
            "description": "Optional user UUID override. Leave empty to use the current workflow caller.",
            "title": "User Id",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.utils.credential.inputs.user_id"
          }
        },
        "required": [
          "bindings"
        ],
        "title": "CredentialInput",
        "type": "object"
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Resolved environment variables ready for injection into downstream nodes.",
        "properties": {
          "env_vars": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Resolved env var values for downstream nodes (sensitive).",
            "title": "Env Vars",
            "type": "object",
            "x-i18n-key": "nodes.utils.credential.outputs.env_vars"
          },
          "missing_bindings": {
            "description": "Env var keys that could not be resolved (only populated when Strict Mode is off).",
            "items": {
              "type": "string"
            },
            "title": "Missing Bindings",
            "type": "array",
            "x-i18n-key": "nodes.utils.credential.outputs.missing_bindings"
          },
          "resolved_count": {
            "description": "How many bindings were resolved successfully.",
            "format": "uint",
            "minimum": 0,
            "title": "Resolved Count",
            "type": "integer",
            "x-i18n-key": "nodes.utils.credential.outputs.resolved_count"
          }
        },
        "required": [
          "env_vars",
          "missing_bindings",
          "resolved_count"
        ],
        "title": "CredentialOutput",
        "type": "object"
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.utils.credential"
    },
    {
      "typeId": "io/video_extract_audio",
      "name": "Video Extract Audio",
      "category": "io",
      "description": "Extract audio track from video file, outputs audio file path. Requires ffmpeg installed on system. Can connect to Speech To Text node for transcription.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "channels": {
            "default": 1,
            "description": "Audio channels: 1=mono (recommended), 2=stereo",
            "format": "uint32",
            "minimum": 0,
            "title": "Channels",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_audio.inputs.channels"
          },
          "duration_seconds": {
            "default": 0,
            "description": "Duration of extracted audio (seconds), 0 means extract to the end",
            "format": "uint32",
            "minimum": 0,
            "title": "Duration Seconds",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_audio.inputs.duration_seconds"
          },
          "file_path": {
            "description": "Local absolute path of the video file (mp4/avi/mov/mkv/webm etc.)",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.io.video_extract_audio.inputs.file_path"
          },
          "output_dir": {
            "default": null,
            "description": "Output directory path, defaults to /tmp/ChengOS/audio/",
            "title": "Output Dir",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.video_extract_audio.inputs.output_dir"
          },
          "output_format": {
            "default": "wav",
            "description": "Output audio format: wav (recommended) / mp3 / ogg / flac",
            "oneOf": [
              {
                "description": "WAV(无损,与 Whisper 兼容性最好)",
                "enum": [
                  "wav"
                ],
                "type": "string"
              },
              {
                "description": "MP3(有损压缩,体积小)",
                "enum": [
                  "mp3"
                ],
                "type": "string"
              },
              {
                "description": "OGG Vorbis",
                "enum": [
                  "ogg"
                ],
                "type": "string"
              },
              {
                "description": "FLAC(无损压缩)",
                "enum": [
                  "flac"
                ],
                "type": "string"
              }
            ],
            "title": "Output Format",
            "x-control": "select",
            "x-i18n-key": "nodes.io.video_extract_audio.inputs.output_format"
          },
          "sample_rate": {
            "default": 16000,
            "description": "Sample rate (Hz), 16000 recommended for Whisper",
            "format": "uint32",
            "minimum": 0,
            "title": "Sample Rate",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_audio.inputs.sample_rate"
          },
          "start_seconds": {
            "default": 0,
            "description": "Start extraction from this second (0 means from the beginning)",
            "format": "uint32",
            "minimum": 0,
            "title": "Start Seconds",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_audio.inputs.start_seconds"
          }
        },
        "required": [
          "file_path"
        ],
        "title": "VideoExtractAudioInput",
        "type": "object",
        "x-field-order": [
          "file_path",
          "output_format",
          "sample_rate",
          "channels",
          "output_dir",
          "start_seconds",
          "duration_seconds"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "audio_file_path": {
            "description": "Extracted audio file path, can connect directly to io/speech_to_text node",
            "title": "Audio File Path",
            "type": "string",
            "x-i18n-key": "nodes.io.video_extract_audio.outputs.audio_file_path"
          },
          "ffmpeg_output": {
            "description": "ffmpeg stderr output, for debugging",
            "title": "Ffmpeg Output",
            "type": "string",
            "x-i18n-key": "nodes.io.video_extract_audio.outputs.ffmpeg_output"
          },
          "file_size": {
            "description": "Size of the extracted audio file (bytes)",
            "format": "uint64",
            "minimum": 0,
            "title": "File Size",
            "type": "integer",
            "x-i18n-key": "nodes.io.video_extract_audio.outputs.file_size"
          },
          "format": {
            "description": "Output audio format (wav / mp3 / ogg / flac)",
            "title": "Format",
            "type": "string",
            "x-i18n-key": "nodes.io.video_extract_audio.outputs.format"
          }
        },
        "required": [
          "audio_file_path",
          "ffmpeg_output",
          "file_size",
          "format"
        ],
        "title": "VideoExtractAudioOutput",
        "type": "object",
        "x-collapsed-visible": [
          "audio_file_path"
        ],
        "x-field-order": [
          "audio_file_path",
          "file_size",
          "format",
          "ffmpeg_output"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.io.video_extract_audio"
    },
    {
      "typeId": "ai/llm",
      "name": "AI Chat",
      "category": "agent",
      "description": "Call large language model for dialogue generation",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input for LLM node.",
        "properties": {
          "context": {
            "additionalProperties": true,
            "default": null,
            "description": "AgentContext (optional, carries conversation history)",
            "title": "Agent Context",
            "type": "object",
            "x-i18n-key": "nodes.ai.llm.inputs.context",
            "x-port": true
          },
          "image_base64": {
            "default": null,
            "description": "Base64 image payload or data URL, connectable from io/file_upload.image_base64",
            "title": "Image Base64",
            "type": "string",
            "x-i18n-key": "nodes.ai.llm.inputs.image_base64",
            "x-port": true
          },
          "llm_config": {
            "additionalProperties": true,
            "description": "LLM configuration (JSON string or object)",
            "title": "LLM Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.ai.llm.inputs.llm_config",
            "x-port": true
          },
          "system_prompt": {
            "default": "",
            "description": "System prompt (optional)",
            "maxLength": 50000,
            "title": "System Prompt",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.ai.llm.inputs.system_prompt"
          },
          "tools": {
            "default": null,
            "description": "Tool/function definitions (JSON array for function calling)",
            "title": "Tools",
            "x-i18n-key": "nodes.ai.llm.inputs.tools"
          },
          "user_message": {
            "default": "",
            "description": "User message (can be empty if context.history already contains user messages)",
            "maxLength": 200000,
            "title": "User Message",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.ai.llm.inputs.user_message"
          },
          "user_message_rich": {
            "additionalProperties": true,
            "default": null,
            "description": "Structured user message with multimodal parts",
            "title": "User Message Rich",
            "type": "object",
            "x-i18n-key": "nodes.ai.llm.inputs.user_message_rich",
            "x-port": true
          }
        },
        "required": [
          "llm_config"
        ],
        "title": "AiLlmInput",
        "type": "object",
        "x-collapsed-visible": [
          "user_message",
          "llm_config"
        ],
        "x-field-order": [
          "context",
          "llm_config",
          "system_prompt",
          "user_message",
          "user_message_rich",
          "image_base64",
          "tools"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "FunctionCall": {
            "description": "Function call details.",
            "properties": {
              "arguments": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "arguments",
              "name"
            ],
            "type": "object"
          },
          "ToolCall": {
            "description": "Tool call made by the LLM.\n\n# Examples\n\n``` use cheng_llm::types::ToolCall;\n\nlet tool_call = ToolCall { id: \"call_123\".to_string(), function: cheng_llm::types::FunctionCall { name: \"get_weather\".to_string(), arguments: r#\"{\"location\": \"Tokyo\"}\"#.to_string(), }, index: None, }; ```",
            "properties": {
              "function": {
                "$ref": "#/definitions/FunctionCall"
              },
              "id": {
                "type": "string"
              },
              "index": {
                "description": "Index in the tool calls array (used for streaming)",
                "format": "uint32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "required": [
              "function",
              "id"
            ],
            "type": "object"
          },
          "ToolExecutionResult": {
            "description": "Result of a single tool execution",
            "properties": {
              "call_id": {
                "description": "Tool call ID (for matching with LLM request)",
                "type": "string"
              },
              "duration_ms": {
                "description": "Execution duration in milliseconds",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "error": {
                "description": "Error message if failed",
                "type": [
                  "string",
                  "null"
                ]
              },
              "output": {
                "description": "Execution output",
                "type": "string"
              },
              "success": {
                "description": "Whether execution succeeded",
                "type": "boolean"
              },
              "tool_name": {
                "description": "Tool name",
                "type": "string"
              }
            },
            "required": [
              "call_id",
              "duration_ms",
              "output",
              "success",
              "tool_name"
            ],
            "type": "object"
          }
        },
        "description": "Output from LLM node.",
        "properties": {
          "completion_tokens": {
            "description": "Tokens used in completion",
            "format": "uint32",
            "minimum": 0,
            "title": "Completion Tokens",
            "type": "integer",
            "x-i18n-key": "nodes.ai.llm.outputs.completion_tokens"
          },
          "context": {
            "additionalProperties": true,
            "description": "AgentContext output port (contains conversation history)",
            "title": "Agent Context",
            "type": "object",
            "x-i18n-key": "nodes.ai.llm.outputs.context",
            "x-port": true
          },
          "finish_reason": {
            "description": "Finish reason",
            "title": "Finish Reason",
            "type": "string",
            "x-i18n-key": "nodes.ai.llm.outputs.finish_reason"
          },
          "llm_config": {
            "additionalProperties": true,
            "description": "LLM configuration used for this call (reusable by downstream nodes)",
            "title": "LLM Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.ai.llm.outputs.llm_config",
            "x-port": true
          },
          "prompt_tokens": {
            "description": "Tokens used in prompt",
            "format": "uint32",
            "minimum": 0,
            "title": "Prompt Tokens",
            "type": "integer",
            "x-i18n-key": "nodes.ai.llm.outputs.prompt_tokens"
          },
          "response": {
            "description": "Generated text response",
            "title": "Response",
            "type": "string",
            "x-i18n-key": "nodes.ai.llm.outputs.response"
          },
          "tool_calls": {
            "description": "Tool calls made by the LLM (for function calling)",
            "items": {
              "$ref": "#/definitions/ToolCall"
            },
            "title": "Tool Calls",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.ai.llm.outputs.tool_calls"
          },
          "tool_results": {
            "description": "Tool execution results (when tools are connected and auto-executed)",
            "items": {
              "$ref": "#/definitions/ToolExecutionResult"
            },
            "title": "Tool Results",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.ai.llm.outputs.tool_results"
          },
          "total_tokens": {
            "description": "Total tokens used",
            "format": "uint32",
            "minimum": 0,
            "title": "Total Tokens",
            "type": "integer",
            "x-i18n-key": "nodes.ai.llm.outputs.total_tokens"
          }
        },
        "required": [
          "completion_tokens",
          "context",
          "finish_reason",
          "llm_config",
          "prompt_tokens",
          "response",
          "total_tokens"
        ],
        "title": "AiLlmOutput",
        "type": "object",
        "x-collapsed-visible": [
          "context",
          "response"
        ],
        "x-field-order": [
          "context",
          "response",
          "prompt_tokens",
          "completion_tokens",
          "total_tokens",
          "finish_reason",
          "tool_calls",
          "tool_results",
          "llm_config"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.ai.llm"
    },
    {
      "typeId": "rag/formatter",
      "name": "RAG Formatter",
      "category": "rag",
      "description": "Format retrieved documents and user query into LLM prompt",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "RetrievedDocOutput": {
            "description": "Retrieved document in output",
            "properties": {
              "chunk_index": {
                "description": "Chunk index",
                "format": "int64",
                "title": "Chunk Index",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "context": {
                "description": "Context description (if available)",
                "type": [
                  "string",
                  "null"
                ]
              },
              "document_id": {
                "description": "Parent document ID",
                "title": "Document Id",
                "type": [
                  "string",
                  "null"
                ]
              },
              "id": {
                "description": "Document chunk ID",
                "type": "string"
              },
              "retrieval_method": {
                "description": "Retrieval method used",
                "title": "Retrieval Method",
                "type": [
                  "string",
                  "null"
                ]
              },
              "score": {
                "description": "Relevance score",
                "format": "float",
                "type": "number"
              },
              "text": {
                "description": "Chunk text content",
                "type": "string"
              }
            },
            "required": [
              "id",
              "score",
              "text"
            ],
            "type": "object"
          }
        },
        "description": "Formatter node input",
        "properties": {
          "custom_template": {
            "default": null,
            "description": "Custom prompt template. Available placeholders: {query}, {documents}, {count}",
            "title": "Custom Template",
            "type": "string",
            "x-conditional": {
              "field": "template",
              "values": [
                "custom"
              ]
            },
            "x-control": "textarea",
            "x-i18n-key": "nodes.rag.formatter.inputs.custom_template"
          },
          "documents": {
            "description": "List of retrieved documents from retriever node output",
            "items": {
              "$ref": "#/definitions/RetrievedDocOutput"
            },
            "title": "Retrieved Documents",
            "type": "array",
            "x-i18n-key": "nodes.rag.formatter.inputs.documents"
          },
          "include_scores": {
            "default": null,
            "description": "Include document relevance scores in formatted output",
            "title": "Show Relevance Scores",
            "type": [
              "boolean",
              "null"
            ],
            "x-i18n-key": "nodes.rag.formatter.inputs.include_scores"
          },
          "include_sources": {
            "default": null,
            "description": "Include document IDs and source information in formatted output",
            "title": "Show Document Sources",
            "type": [
              "boolean",
              "null"
            ],
            "x-i18n-key": "nodes.rag.formatter.inputs.include_sources"
          },
          "max_doc_chars": {
            "default": null,
            "description": "Maximum characters per document chunk (0 = unlimited)",
            "format": "uint",
            "minimum": 0,
            "title": "Max Characters per Document",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.rag.formatter.inputs.max_doc_chars"
          },
          "query": {
            "description": "User question from retriever node query output",
            "title": "Query Text",
            "type": "string",
            "x-i18n-key": "nodes.rag.formatter.inputs.query"
          },
          "template": {
            "default": null,
            "description": "Select prompt template type",
            "title": "Template Type",
            "type": "string",
            "x-control": "select",
            "x-default": "qa",
            "x-i18n-key": "nodes.rag.formatter.inputs.template",
            "x-options": [
              {
                "description": "Standard question and answer template",
                "label": "Q&A",
                "value": "qa"
              },
              {
                "description": "Document summary generation template",
                "label": "Summary",
                "value": "summary"
              },
              {
                "description": "Use custom template",
                "label": "Custom",
                "value": "custom"
              }
            ]
          }
        },
        "required": [
          "documents",
          "query"
        ],
        "title": "FormatterInput",
        "type": "object",
        "x-field-order": [
          "query",
          "documents",
          "template",
          "custom_template",
          "include_scores",
          "include_sources",
          "max_doc_chars"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Formatter node output",
        "properties": {
          "document_count": {
            "description": "Number of documents included",
            "format": "uint",
            "minimum": 0,
            "title": "Document Count",
            "type": "integer",
            "x-i18n-key": "nodes.rag.formatter.outputs.document_count"
          },
          "prompt": {
            "description": "Formatted prompt ready for LLM input",
            "title": "Prompt",
            "type": "string",
            "x-i18n-key": "nodes.rag.formatter.outputs.prompt"
          },
          "query": {
            "description": "Original query text",
            "title": "Query",
            "type": "string",
            "x-i18n-key": "nodes.rag.formatter.outputs.query"
          },
          "total_chars": {
            "description": "Total characters in formatted output",
            "format": "uint",
            "minimum": 0,
            "title": "Total Chars",
            "type": "integer",
            "x-i18n-key": "nodes.rag.formatter.outputs.total_chars"
          }
        },
        "required": [
          "document_count",
          "prompt",
          "query",
          "total_chars"
        ],
        "title": "FormatterOutput",
        "type": "object",
        "x-collapsed-visible": [
          "prompt"
        ],
        "x-field-order": [
          "prompt",
          "query",
          "document_count",
          "total_chars"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.rag.formatter"
    },
    {
      "typeId": "utils/preview",
      "name": "Content Preview",
      "category": "utils",
      "description": "Display output results in preview window, supports multiple formats and statistics",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "context": {
            "description": "Context from Chat node",
            "title": "Context",
            "x-i18n-key": "nodes.utils.preview.inputs.context"
          },
          "currentPage": {
            "default": 1,
            "description": "Current page number",
            "format": "uint",
            "minimum": 1,
            "title": "Current Page",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.utils.preview.inputs.currentPage"
          },
          "data": {
            "description": "Data to preview",
            "title": "Data",
            "x-i18n-key": "nodes.utils.preview.inputs.data"
          },
          "displayFormat": {
            "default": "raw",
            "description": "Select preview display format",
            "oneOf": [
              {
                "description": "原始格式",
                "enum": [
                  "raw"
                ],
                "type": "string"
              },
              {
                "description": "JSON 格式化",
                "enum": [
                  "json"
                ],
                "type": "string"
              },
              {
                "description": "表格视图",
                "enum": [
                  "table"
                ],
                "type": "string"
              },
              {
                "description": "代码块格式",
                "enum": [
                  "codeblock"
                ],
                "type": "string"
              },
              {
                "description": "提取助手消息",
                "enum": [
                  "assistantmessage"
                ],
                "type": "string"
              }
            ],
            "title": "Display Format",
            "x-control": "select",
            "x-i18n-key": "nodes.utils.preview.inputs.displayFormat"
          },
          "pageLength": {
            "default": 1000,
            "description": "Characters per page; shorter content displays directly, longer content is paginated",
            "format": "uint",
            "maximum": 10000,
            "minimum": 100,
            "title": "Page Length",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.utils.preview.inputs.pageLength"
          },
          "showStats": {
            "default": true,
            "description": "Whether to show character count, line count and other statistics",
            "title": "Show Stats",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.utils.preview.inputs.showStats"
          }
        },
        "title": "PreviewInput",
        "type": "object",
        "x-collapsed-visible": [
          "context"
        ],
        "x-field-order": [
          "data",
          "context",
          "display_format",
          "show_stats",
          "page_length",
          "current_page"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "original_data": {
            "description": "Original input data",
            "title": "Original Data",
            "x-i18n-key": "nodes.utils.preview.outputs.original_data"
          },
          "pagination": {
            "description": "Pagination info (provided when content needs pagination)",
            "title": "Pagination",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.utils.preview.outputs.pagination"
          },
          "preview_content": {
            "description": "Formatted preview content",
            "title": "Preview Content",
            "type": "string",
            "x-i18n-key": "nodes.utils.preview.outputs.preview_content"
          },
          "statistics": {
            "description": "Data statistics",
            "title": "Statistics",
            "type": "string",
            "x-i18n-key": "nodes.utils.preview.outputs.statistics"
          }
        },
        "required": [
          "original_data",
          "preview_content",
          "statistics"
        ],
        "title": "PreviewOutput",
        "type": "object",
        "x-collapsed-visible": [],
        "x-field-order": [
          "original_data",
          "preview_content",
          "statistics",
          "pagination"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.utils.preview"
    },
    {
      "typeId": "tools/delete_file",
      "name": "Delete File",
      "category": "tools",
      "description": "Delete file (high side-effect, irreversible). Only allows deleting files, not directories. Supports dry_run rehearsal mode.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "dry_run": {
            "default": false,
            "description": "Dry run mode (validate only, no actual deletion), default false",
            "title": "Dry Run",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.delete_file.inputs.dry_run"
          },
          "file_path": {
            "description": "Absolute file path to delete",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.delete_file.inputs.file_path"
          }
        },
        "required": [
          "file_path"
        ],
        "title": "DeleteFileInput",
        "type": "object"
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "deleted": {
            "description": "true=成功删除(dry_run=true 时表示\"可以删除\")",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.delete_file.outputs.deleted"
          },
          "dry_run": {
            "description": "是否为演练模式",
            "title": "Dry Run",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.delete_file.outputs.dry_run"
          },
          "error": {
            "description": "错误信息",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.delete_file.outputs.error"
          },
          "file_path": {
            "description": "操作的文件路径",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.delete_file.outputs.file_path"
          },
          "file_size_bytes": {
            "description": "被删除文件的大小(删除前记录)",
            "format": "uint64",
            "minimum": 0,
            "title": "File Size Bytes",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.delete_file.outputs.file_size_bytes"
          }
        },
        "required": [
          "deleted",
          "dry_run",
          "file_path"
        ],
        "title": "DeleteFileOutput",
        "type": "object",
        "x-collapsed-visible": [
          "deleted"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.delete_file"
    },
    {
      "typeId": "io/file_upload",
      "name": "File Upload",
      "category": "io",
      "description": "Handle file uploads, supports images, documents and other formats, optional OCR and document parsing",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "文件上传节点输入",
        "properties": {
          "allowed_category": {
            "default": "auto",
            "description": "Restrict allowed file category",
            "oneOf": [
              {
                "description": "自动检测",
                "enum": [
                  "auto"
                ],
                "type": "string"
              },
              {
                "description": "图片",
                "enum": [
                  "image"
                ],
                "type": "string"
              },
              {
                "description": "文档",
                "enum": [
                  "document"
                ],
                "type": "string"
              },
              {
                "description": "音频",
                "enum": [
                  "audio"
                ],
                "type": "string"
              },
              {
                "description": "视频",
                "enum": [
                  "video"
                ],
                "type": "string"
              },
              {
                "description": "其他",
                "enum": [
                  "other"
                ],
                "type": "string"
              }
            ],
            "title": "Allowed Category",
            "x-control": "select",
            "x-i18n-key": "nodes.io.file_upload.inputs.allowed_category"
          },
          "enable_ocr": {
            "default": false,
            "description": "Enable OCR recognition for images",
            "title": "Enable OCR",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.io.file_upload.inputs.enable_ocr"
          },
          "files_json": {
            "anyOf": [
              {
                "type": "array"
              },
              {
                "type": "object"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Upload files via picker or drag-and-drop; also accepts JSON from upstream",
            "title": "Upload Files",
            "x-control": "file-upload",
            "x-i18n-key": "nodes.io.file_upload.inputs.files_json",
            "x-multiple": true
          },
          "max_file_size_mb": {
            "default": 50,
            "description": "Maximum size per file (MB)",
            "format": "uint64",
            "maximum": 500,
            "minimum": 1,
            "title": "Max File Size (MB)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.file_upload.inputs.max_file_size_mb"
          },
          "parse_documents": {
            "default": false,
            "description": "Parse document content (PDF, Word, etc.)",
            "title": "Parse Documents",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.io.file_upload.inputs.parse_documents"
          }
        },
        "title": "FileUploadInput",
        "type": "object",
        "x-field-order": [
          "files_json",
          "allowed_category",
          "max_file_size_mb",
          "enable_ocr",
          "parse_documents"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "FileCategory": {
            "description": "文件类别",
            "oneOf": [
              {
                "description": "自动检测",
                "enum": [
                  "auto"
                ],
                "type": "string"
              },
              {
                "description": "图片",
                "enum": [
                  "image"
                ],
                "type": "string"
              },
              {
                "description": "文档",
                "enum": [
                  "document"
                ],
                "type": "string"
              },
              {
                "description": "音频",
                "enum": [
                  "audio"
                ],
                "type": "string"
              },
              {
                "description": "视频",
                "enum": [
                  "video"
                ],
                "type": "string"
              },
              {
                "description": "其他",
                "enum": [
                  "other"
                ],
                "type": "string"
              }
            ]
          },
          "FileInfo": {
            "description": "单个文件信息",
            "properties": {
              "base64_content": {
                "description": "Base64 编码内容(小文件可直接内联)",
                "type": [
                  "string",
                  "null"
                ]
              },
              "category": {
                "allOf": [
                  {
                    "$ref": "#/definitions/FileCategory"
                  }
                ],
                "description": "文件类别"
              },
              "filename": {
                "description": "文件名",
                "type": "string"
              },
              "id": {
                "description": "文件 ID(唯一标识符)",
                "type": "string"
              },
              "metadata": {
                "default": null,
                "description": "附加元数据"
              },
              "mime_type": {
                "description": "MIME 类型",
                "type": "string"
              },
              "size": {
                "description": "文件大小(字节)",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "url": {
                "description": "文件 URL(访问地址)",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "category",
              "filename",
              "id",
              "mime_type",
              "size"
            ],
            "type": "object"
          }
        },
        "description": "文件上传节点输出",
        "properties": {
          "audio_base64": {
            "description": "Base64 content of the first audio file, can connect directly to io/speech_to_text.base64_content",
            "title": "Audio Base64",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.file_upload.outputs.audio_base64"
          },
          "audio_filename": {
            "description": "Filename of the first audio file, can connect directly to io/speech_to_text.filename",
            "title": "Audio Filename",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.file_upload.outputs.audio_filename"
          },
          "chat_input_raw": {
            "description": "RawPayload[] JSON for direct connection to chat/input.raw_input",
            "title": "Chat Input Raw",
            "type": "string",
            "x-i18n-key": "nodes.io.file_upload.outputs.chat_input_raw",
            "x-port": true
          },
          "document_base64": {
            "description": "Base64 content of the first document file, can connect directly to io/document_to_text.base64_content",
            "title": "Document Base64",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.file_upload.outputs.document_base64"
          },
          "document_filename": {
            "description": "Filename of the first document file, can connect directly to io/document_to_text.filename",
            "title": "Document Filename",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.file_upload.outputs.document_filename"
          },
          "errors": {
            "description": "Error messages during processing",
            "items": {
              "type": "string"
            },
            "title": "Errors",
            "type": "array",
            "x-i18n-key": "nodes.io.file_upload.outputs.errors"
          },
          "file_count": {
            "description": "Number of files successfully processed",
            "format": "uint",
            "minimum": 0,
            "title": "File Count",
            "type": "integer",
            "x-i18n-key": "nodes.io.file_upload.outputs.file_count"
          },
          "files": {
            "description": "List of processed file information",
            "items": {
              "$ref": "#/definitions/FileInfo"
            },
            "title": "Files",
            "type": "array",
            "x-i18n-key": "nodes.io.file_upload.outputs.files"
          },
          "image_base64": {
            "description": "Base64 content of the first image file, can connect directly to ai/llm.image_base64",
            "title": "Image Base64",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.file_upload.outputs.image_base64"
          },
          "total_size": {
            "description": "Total size of all files (bytes)",
            "format": "uint64",
            "minimum": 0,
            "title": "Total Size",
            "type": "integer",
            "x-i18n-key": "nodes.io.file_upload.outputs.total_size"
          },
          "user_message_rich": {
            "additionalProperties": true,
            "description": "Structured user message with multimodal parts",
            "title": "User Message Rich",
            "type": "object",
            "x-i18n-key": "nodes.io.file_upload.outputs.user_message_rich",
            "x-port": true
          },
          "video_file_path": {
            "description": "Local path of the first video file, can connect directly to io/video_extract_audio.file_path or io/video_extract_frames.file_path",
            "title": "Video File Path",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.file_upload.outputs.video_file_path"
          }
        },
        "required": [
          "chat_input_raw",
          "errors",
          "file_count",
          "files",
          "total_size",
          "user_message_rich"
        ],
        "title": "FileUploadOutput",
        "type": "object",
        "x-collapsed-visible": [
          "document_base64",
          "document_filename",
          "audio_base64",
          "audio_filename",
          "video_file_path",
          "image_base64",
          "chat_input_raw",
          "user_message_rich"
        ],
        "x-field-order": [
          "files",
          "file_count",
          "total_size",
          "errors",
          "document_base64",
          "document_filename",
          "audio_base64",
          "audio_filename",
          "video_file_path",
          "image_base64",
          "chat_input_raw",
          "user_message_rich"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.io.file_upload"
    },
    {
      "typeId": "tools/code_python",
      "name": "Python Executor",
      "category": "tools",
      "description": "Run Python 3 scripts (native python3, NO OS-level isolation — trusted environment only). FAIL-CLOSED: errors if python3 runtime is unavailable. Use for: algorithms, text processing, data transformation, scientific computing. Do NOT use for network requests (→ Shell) or simple JSON/string transforms (→ JS). Network access is disabled on this node by design. Example: {\"script\":\"result = sum(input['values'])\",\"input\":{\"values\":[1,2,3]}}",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "allow_filesystem": {
            "default": false,
            "description": "Whether to allow script to write files to workspace",
            "title": "Allow Filesystem Write",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.code_python.inputs.allow_filesystem"
          },
          "allow_full_disk_readonly": {
            "default": false,
            "description": "Whether to allow read-only access to entire disk (for disk-wide search/file finding).",
            "title": "Allow Full Disk Read",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.code_python.inputs.allow_full_disk_readonly"
          },
          "input": {
            "default": null,
            "description": "Input data (any JSON), accessible via `input` variable in script",
            "title": "Input",
            "x-i18n-key": "nodes.tools.code_python.inputs.input"
          },
          "memory_mb": {
            "default": 128,
            "description": "Memory limit in MB. Soft constraint only, no OS-level enforcement. Default 128MB.",
            "format": "uint64",
            "maximum": 1024,
            "minimum": 16,
            "title": "Memory Limit (MB)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.code_python.inputs.memory_mb"
          },
          "script": {
            "default": null,
            "description": "[Required] Python 3 script. Example: result = sum(input['values'])",
            "title": "Script",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.tools.code_python.inputs.script",
            "x-rows": 5
          },
          "timeout_ms": {
            "default": 5000,
            "description": "Timeout in milliseconds. Default 5000ms, max 300000ms.",
            "format": "uint64",
            "maximum": 300000,
            "minimum": 100,
            "title": "Timeout (ms)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.code_python.inputs.timeout_ms"
          },
          "workspace_name": {
            "default": null,
            "description": "Workspace name (e.g. project-alpha), only allows letters/digits/-/_.",
            "title": "Workspace Name",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.code_python.inputs.workspace_name"
          }
        },
        "title": "CodePythonInput",
        "type": "object",
        "x-collapsed-visible": [
          "script"
        ],
        "x-field-order": [
          "input",
          "script",
          "workspace_name",
          "allow_filesystem",
          "allow_full_disk_readonly",
          "timeout_ms",
          "memory_mb"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "ExecutionMetrics": {
            "properties": {
              "duration_ms": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "input_size_bytes": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "output_size_bytes": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "peak_memory_bytes": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "runtime_type": {
                "type": "string"
              },
              "script_hash": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "duration_ms",
              "input_size_bytes",
              "output_size_bytes",
              "peak_memory_bytes",
              "runtime_type"
            ],
            "type": "object"
          }
        },
        "properties": {
          "isolation_level": {
            "description": "Actual isolation level used: bubblewrap > quickjs > python",
            "title": "Isolation Level",
            "type": "string",
            "x-i18n-key": "nodes.tools.code_python.outputs.isolation_level"
          },
          "metrics": {
            "allOf": [
              {
                "$ref": "#/definitions/ExecutionMetrics"
              }
            ],
            "description": "Execution performance metrics",
            "title": "Metrics",
            "x-i18n-key": "nodes.tools.code_python.outputs.metrics"
          },
          "result": {
            "description": "Script execution result",
            "title": "Result",
            "x-i18n-key": "nodes.tools.code_python.outputs.result"
          },
          "stderr": {
            "description": "Standard error",
            "title": "Stderr",
            "type": "string",
            "x-i18n-key": "nodes.tools.code_python.outputs.stderr"
          },
          "stdout": {
            "description": "Standard output",
            "title": "Stdout",
            "type": "string",
            "x-i18n-key": "nodes.tools.code_python.outputs.stdout"
          },
          "warnings": {
            "description": "Script validation warnings",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array",
            "x-i18n-key": "nodes.tools.code_python.outputs.warnings"
          }
        },
        "required": [
          "isolation_level",
          "metrics",
          "result",
          "stderr",
          "stdout",
          "warnings"
        ],
        "title": "CodeOutput",
        "type": "object",
        "x-collapsed-visible": [
          "result"
        ],
        "x-field-order": [
          "result",
          "isolation_level",
          "metrics",
          "stdout",
          "stderr",
          "warnings"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.code_python"
    },
    {
      "typeId": "tools/mail",
      "name": "Mail Tool",
      "category": "tools",
      "description": "Operate real emails via IMAP/SMTP protocols: send, read, search, move, mark, reply, forward and more",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "EmailFormat": {
            "description": "邮件正文格式",
            "oneOf": [
              {
                "description": "纯文本",
                "enum": [
                  "text"
                ],
                "type": "string"
              },
              {
                "description": "HTML 格式",
                "enum": [
                  "html"
                ],
                "type": "string"
              },
              {
                "description": "同时发送纯文本和 HTML(推荐,兼容性最好)",
                "enum": [
                  "both"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "邮件工具输入",
        "properties": {
          "bcc": {
            "description": "BCC email address, multiple addresses separated by commas",
            "title": "BCC",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.bcc"
          },
          "body": {
            "description": "Email body content",
            "title": "Body",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.body"
          },
          "cc": {
            "description": "CC email address, multiple addresses separated by commas",
            "title": "CC",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.cc"
          },
          "display_name": {
            "description": "Sender display name (e.g. John Doe), leave empty to show only email address",
            "title": "Display Name",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.display_name"
          },
          "email_id": {
            "description": "Email unique identifier (obtained from id field in ListEmails/SearchEmails results)",
            "title": "Email ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.email_id"
          },
          "folder": {
            "default": "INBOX",
            "description": "Mail folder name (default INBOX, sent usually Sent or [Gmail]/Sent Mail)",
            "title": "Folder",
            "type": "string",
            "x-i18n-key": "nodes.tools.mail.inputs.folder"
          },
          "format": {
            "allOf": [
              {
                "$ref": "#/definitions/EmailFormat"
              }
            ],
            "description": "Body format: text (plain text), html (HTML), both (send both, recommended)",
            "title": "Format",
            "x-i18n-key": "nodes.tools.mail.inputs.format"
          },
          "imap_credential_id": {
            "default": null,
            "description": "IMAP credential for receiving operations (read, search, move, delete etc. - ListEmails/SearchEmails/GetEmail/MoveEmail etc.)",
            "title": "IMAP Credential",
            "type": "string",
            "x-control": "credential-select",
            "x-credential-providers": [
              "imap"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.imap_credential_id"
          },
          "operation": {
            "description": "Email operation type to execute",
            "oneOf": [
              {
                "description": "发送邮件(需 SMTP 配置)",
                "enum": [
                  "send_email"
                ],
                "type": "string"
              },
              {
                "description": "获取邮件列表(需 IMAP 配置)",
                "enum": [
                  "list_emails"
                ],
                "type": "string"
              },
              {
                "description": "搜索邮件(需 IMAP 配置)",
                "enum": [
                  "search_emails"
                ],
                "type": "string"
              },
              {
                "description": "获取邮件详情及正文(需 IMAP 配置)",
                "enum": [
                  "get_email"
                ],
                "type": "string"
              },
              {
                "description": "移动邮件到指定文件夹",
                "enum": [
                  "move_email"
                ],
                "type": "string"
              },
              {
                "description": "复制邮件到指定文件夹",
                "enum": [
                  "copy_email"
                ],
                "type": "string"
              },
              {
                "description": "删除邮件",
                "enum": [
                  "delete_email"
                ],
                "type": "string"
              },
              {
                "description": "标记邮件为已读",
                "enum": [
                  "mark_as_read"
                ],
                "type": "string"
              },
              {
                "description": "标记邮件为未读",
                "enum": [
                  "mark_as_unread"
                ],
                "type": "string"
              },
              {
                "description": "列出所有邮件文件夹",
                "enum": [
                  "list_folders"
                ],
                "type": "string"
              },
              {
                "description": "回复邮件(需 IMAP + SMTP 配置)",
                "enum": [
                  "reply_email"
                ],
                "type": "string"
              },
              {
                "description": "转发邮件(需 IMAP + SMTP 配置)",
                "enum": [
                  "forward_email"
                ],
                "type": "string"
              }
            ],
            "title": "Operation",
            "x-control": "select",
            "x-i18n-key": "nodes.tools.mail.inputs.operation"
          },
          "page": {
            "default": 1,
            "description": "Page number starting from 1 (default 1, newest emails on page 1)",
            "format": "uint32",
            "minimum": 0,
            "title": "Page",
            "type": "integer",
            "x-i18n-key": "nodes.tools.mail.inputs.page"
          },
          "page_size": {
            "default": 20,
            "description": "Number of emails per page (default 20, max 50)",
            "format": "uint32",
            "minimum": 0,
            "title": "Page Size",
            "type": "integer",
            "x-i18n-key": "nodes.tools.mail.inputs.page_size"
          },
          "query": {
            "description": "IMAP search syntax: FROM \"[email protected]\", SUBJECT \"keyword\", UNSEEN (unread), SINCE \"1-Jan-2024\", can be combined",
            "title": "Search Query",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.query"
          },
          "smtp_credential_id": {
            "default": null,
            "description": "SMTP credential for sending operations (SendEmail/ReplyEmail/ForwardEmail)",
            "title": "SMTP Credential",
            "type": "string",
            "x-control": "credential-select",
            "x-credential-providers": [
              "smtp"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.smtp_credential_id"
          },
          "subject": {
            "description": "Email subject",
            "title": "Subject",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.subject"
          },
          "target_folder": {
            "description": "Target folder name for moving or copying emails (e.g. Archive, Trash, [Gmail]/All Mail)",
            "title": "Target Folder",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.target_folder"
          },
          "to": {
            "description": "Recipient email address, multiple addresses separated by commas",
            "title": "To",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mail.inputs.to"
          }
        },
        "title": "MailInput",
        "type": "object",
        "x-collapsed-visible": [
          "imap_credential_id",
          "smtp_credential_id",
          "operation"
        ],
        "x-field-order": [
          "imap_credential_id",
          "smtp_credential_id",
          "operation",
          "display_name",
          "folder",
          "page",
          "page_size",
          "to",
          "cc",
          "bcc",
          "subject",
          "body",
          "format",
          "query",
          "email_id",
          "target_folder"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "EmailAttachment": {
            "description": "邮件附件信息",
            "properties": {
              "filename": {
                "description": "Attachment filename",
                "title": "Filename",
                "type": "string"
              },
              "mime_type": {
                "description": "Attachment MIME type (e.g. application/pdf, image/png)",
                "title": "Mime Type",
                "type": "string"
              },
              "size": {
                "description": "Attachment file size in bytes, some email servers don't provide this info",
                "format": "uint64",
                "minimum": 0,
                "title": "Size",
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "required": [
              "filename",
              "mime_type"
            ],
            "type": "object"
          },
          "EmailInfo": {
            "description": "单封邮件信息",
            "properties": {
              "attachments": {
                "description": "Email attachment list",
                "items": {
                  "$ref": "#/definitions/EmailAttachment"
                },
                "title": "Attachments",
                "type": "array"
              },
              "body": {
                "description": "Email body content (plain text, only returned by GetEmail operation)",
                "title": "Body",
                "type": [
                  "string",
                  "null"
                ]
              },
              "date": {
                "description": "Email sent time",
                "title": "Date",
                "type": "string"
              },
              "from": {
                "description": "Sender address",
                "title": "From",
                "type": "string"
              },
              "id": {
                "description": "Email unique identifier, can be passed to other operations",
                "title": "ID",
                "type": "string"
              },
              "is_read": {
                "description": "Whether email is read",
                "title": "Is Read",
                "type": "boolean"
              },
              "subject": {
                "description": "Email subject",
                "title": "Subject",
                "type": "string"
              },
              "to": {
                "description": "Recipient address list",
                "items": {
                  "type": "string"
                },
                "title": "To",
                "type": "array"
              }
            },
            "required": [
              "attachments",
              "date",
              "from",
              "id",
              "is_read",
              "subject",
              "to"
            ],
            "type": "object"
          }
        },
        "description": "邮件工具输出",
        "properties": {
          "count": {
            "description": "Number of emails returned this time",
            "format": "uint32",
            "minimum": 0,
            "title": "Count",
            "type": "integer",
            "x-i18n-key": "nodes.tools.mail.outputs.count"
          },
          "emails": {
            "description": "Email list",
            "items": {
              "$ref": "#/definitions/EmailInfo"
            },
            "title": "Emails",
            "type": "array",
            "x-i18n-key": "nodes.tools.mail.outputs.emails"
          },
          "folders": {
            "description": "Mail folder name list",
            "items": {
              "type": "string"
            },
            "title": "Folders",
            "type": "array",
            "x-i18n-key": "nodes.tools.mail.outputs.folders"
          },
          "message": {
            "description": "Operation result description",
            "title": "Message",
            "type": "string",
            "x-i18n-key": "nodes.tools.mail.outputs.message"
          },
          "page": {
            "description": "Current page number",
            "format": "uint32",
            "minimum": 0,
            "title": "Page",
            "type": "integer",
            "x-i18n-key": "nodes.tools.mail.outputs.page"
          },
          "success": {
            "description": "Whether operation succeeded",
            "title": "Success",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.mail.outputs.success"
          },
          "total_count": {
            "description": "Total email count in folder (only provided by ListEmails)",
            "format": "uint32",
            "minimum": 0,
            "title": "Total Count",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mail.outputs.total_count"
          }
        },
        "required": [
          "count",
          "emails",
          "folders",
          "message",
          "page",
          "success"
        ],
        "title": "MailOutput",
        "type": "object",
        "x-collapsed-visible": [
          "imap_credential_id",
          "smtp_credential_id",
          "operation"
        ],
        "x-field-order": [
          "success",
          "message",
          "emails",
          "folders",
          "page",
          "count",
          "total_count"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.mail"
    },
    {
      "typeId": "document/format_for_llm",
      "name": "Format Document (LLM)",
      "category": "document",
      "description": "Read and format document for LLM use, supports priority and tag filtering",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input for DocumentFormatForLlmNode",
        "properties": {
          "context": {
            "additionalProperties": true,
            "default": null,
            "description": "AgentContext port",
            "title": "Context",
            "type": "object",
            "x-i18n-key": "nodes.document.format_for_llm.inputs.context",
            "x-port": true
          },
          "document_id": {
            "description": "Select a document to read, searchable by name",
            "type": "string",
            "x-api-endpoint": "/api/v1/documents?limit=200",
            "x-cache-key": "static_select:/api/v1/documents?limit=200",
            "x-control": "dynamic-select",
            "x-i18n-key": "nodes.document.format_for_llm.inputs.document_id"
          },
          "include_metadata": {
            "default": true,
            "description": "Whether to include block tags and priority info in output",
            "title": "Include Metadata",
            "type": "boolean",
            "x-i18n-key": "nodes.document.format_for_llm.inputs.include_metadata"
          },
          "max_chars": {
            "default": 0,
            "description": "Maximum character limit (0 means unlimited)",
            "format": "uint",
            "maximum": 1000000,
            "minimum": 0,
            "type": "integer",
            "x-i18n-key": "nodes.document.format_for_llm.inputs.max_chars"
          },
          "output_format": {
            "default": "markdown",
            "description": "Output format",
            "oneOf": [
              {
                "description": "Markdown 格式",
                "enum": [
                  "markdown"
                ],
                "type": "string"
              },
              {
                "description": "纯文本",
                "enum": [
                  "plain_text"
                ],
                "type": "string"
              },
              {
                "description": "结构化(包含块信息)",
                "enum": [
                  "structured"
                ],
                "type": "string"
              }
            ],
            "x-control": "select",
            "x-i18n-key": "nodes.document.format_for_llm.inputs.output_format"
          },
          "priority_filter": {
            "default": "all",
            "description": "Filter blocks by priority",
            "oneOf": [
              {
                "description": "所有优先级",
                "enum": [
                  "all"
                ],
                "type": "string"
              },
              {
                "description": "仅高优先级(High + Critical)",
                "enum": [
                  "high_only"
                ],
                "type": "string"
              },
              {
                "description": "仅 Critical",
                "enum": [
                  "critical_only"
                ],
                "type": "string"
              },
              {
                "description": "Normal 及以上(Normal + High + Critical)",
                "enum": [
                  "normal_and_above"
                ],
                "type": "string"
              }
            ],
            "x-control": "select",
            "x-i18n-key": "nodes.document.format_for_llm.inputs.priority_filter"
          },
          "sort_order": {
            "default": "original",
            "description": "Block sort order",
            "oneOf": [
              {
                "description": "按文档原始顺序",
                "enum": [
                  "original"
                ],
                "type": "string"
              },
              {
                "description": "按优先级降序(Critical -> High -> Normal -> Low)",
                "enum": [
                  "priority_desc"
                ],
                "type": "string"
              },
              {
                "description": "按优先级升序(Low -> Normal -> High -> Critical)",
                "enum": [
                  "priority_asc"
                ],
                "type": "string"
              }
            ],
            "x-control": "select",
            "x-i18n-key": "nodes.document.format_for_llm.inputs.sort_order"
          },
          "system_prompt": {
            "default": null,
            "description": "Custom system prompt (optional)",
            "maxLength": 10000,
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.document.format_for_llm.inputs.system_prompt"
          },
          "tag_filter": {
            "default": null,
            "description": "Filter by tags (comma-separated, e.g.: core concepts,API)",
            "maxLength": 500,
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.format_for_llm.inputs.tag_filter"
          }
        },
        "required": [
          "document_id"
        ],
        "title": "DocumentFormatForLlmInput",
        "type": "object",
        "x-field-order": [
          "context",
          "document_id",
          "priority_filter",
          "tag_filter",
          "sort_order",
          "output_format",
          "include_metadata",
          "system_prompt",
          "max_chars"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "FormattedBlock": {
            "description": "格式化后的块信息",
            "properties": {
              "block_type": {
                "description": "块类型",
                "type": "string"
              },
              "content": {
                "description": "内容",
                "type": "string"
              },
              "id": {
                "description": "块 ID",
                "type": "string"
              },
              "priority": {
                "description": "优先级",
                "type": "string"
              },
              "tags": {
                "description": "标签",
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "required": [
              "block_type",
              "content",
              "id",
              "priority",
              "tags"
            ],
            "type": "object"
          }
        },
        "description": "Output from DocumentFormatForLlmNode",
        "properties": {
          "block_count": {
            "description": "处理的块数量",
            "format": "uint",
            "minimum": 0,
            "title": "Block Count",
            "type": "integer",
            "x-i18n-key": "nodes.document.format_for_llm.outputs.block_count"
          },
          "blocks": {
            "description": "Structured block list",
            "items": {
              "$ref": "#/definitions/FormattedBlock"
            },
            "title": "Blocks",
            "type": "array",
            "x-i18n-key": "nodes.document.format_for_llm.outputs.blocks"
          },
          "character_count": {
            "description": "总字符数",
            "format": "uint",
            "minimum": 0,
            "title": "Character Count",
            "type": "integer",
            "x-i18n-key": "nodes.document.format_for_llm.outputs.character_count"
          },
          "context": {
            "additionalProperties": true,
            "description": "AgentContext port",
            "title": "Context",
            "type": "object",
            "x-i18n-key": "nodes.document.format_for_llm.outputs.context",
            "x-port": true
          },
          "error": {
            "description": "错误信息",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.format_for_llm.outputs.error"
          },
          "filtered_block_count": {
            "description": "过滤后的块数量",
            "format": "uint",
            "minimum": 0,
            "title": "Filtered Block Count",
            "type": "integer",
            "x-i18n-key": "nodes.document.format_for_llm.outputs.filtered_block_count"
          },
          "formatted_content": {
            "description": "Formatted document content",
            "title": "Formatted Content",
            "type": "string",
            "x-i18n-key": "nodes.document.format_for_llm.outputs.formatted_content"
          },
          "preview_content": {
            "description": "Preview-friendly document summary with title, character count, and content excerpt",
            "type": "string",
            "x-i18n-key": "nodes.document.format_for_llm.outputs.preview_content"
          },
          "success": {
            "description": "是否成功",
            "type": "boolean",
            "x-i18n-key": "nodes.document.format_for_llm.outputs.success"
          },
          "title": {
            "description": "文档标题",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.format_for_llm.outputs.title"
          },
          "truncated": {
            "description": "是否被截断",
            "type": "boolean",
            "x-i18n-key": "nodes.document.format_for_llm.outputs.truncated"
          }
        },
        "required": [
          "block_count",
          "blocks",
          "character_count",
          "context",
          "filtered_block_count",
          "formatted_content",
          "preview_content",
          "success",
          "truncated"
        ],
        "title": "DocumentFormatForLlmOutput",
        "type": "object",
        "x-collapsed-visible": [
          "context",
          "formatted_content"
        ],
        "x-field-order": [
          "context",
          "formatted_content",
          "preview_content",
          "blocks",
          "title",
          "block_count",
          "filtered_block_count",
          "character_count",
          "truncated",
          "success",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.document.format_for_llm"
    },
    {
      "typeId": "utils/smart_var",
      "name": "Smart Variable Node",
      "category": "utils",
      "description": "Auto-detect text variables, dynamically generate ports, support full output and picked variable extraction",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "extract_mode": {
            "default": "auto",
            "description": "Extract mode: auto=auto-detect key names, manual={{var}} syntax only",
            "enum": [
              "auto",
              "manual"
            ],
            "options": [
              {
                "label": "auto",
                "value": "auto"
              },
              {
                "label": "manual",
                "value": "manual"
              }
            ],
            "title": "Extract Mode",
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.utils.smart_var.inputs.extract_mode"
          },
          "output_vars": {
            "default": [],
            "description": "List of variables to include in output",
            "items": {
              "type": "string"
            },
            "title": "Output Vars",
            "type": "array",
            "x-control": "multi-select",
            "x-i18n-key": "nodes.utils.smart_var.inputs.output_vars",
            "x-options-source": "ports"
          },
          "template": {
            "description": "Raw text (supports JSON/curl/YAML, etc.)",
            "maxLength": 50000,
            "minLength": 1,
            "title": "Template",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.utils.smart_var.inputs.template"
          }
        },
        "required": [
          "template"
        ],
        "title": "SmartVarInput",
        "type": "object",
        "x-field-order": [
          "template",
          "extract_mode",
          "output_vars",
          "dynamic_values"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "VarStatistics": {
            "description": "变量统计信息",
            "properties": {
              "connected_variables": {
                "description": "Connected variables count",
                "format": "uint",
                "minimum": 0,
                "title": "Connected Variables",
                "type": "integer"
              },
              "default_variables": {
                "description": "Default-valued variables count",
                "format": "uint",
                "minimum": 0,
                "title": "Default Variables",
                "type": "integer"
              },
              "missing_variables": {
                "description": "Missing variables count",
                "format": "uint",
                "minimum": 0,
                "title": "Missing Variables",
                "type": "integer"
              },
              "output_size": {
                "description": "Output character count",
                "format": "uint",
                "minimum": 0,
                "title": "Output Size",
                "type": "integer"
              },
              "template_size": {
                "description": "Template character count",
                "format": "uint",
                "minimum": 0,
                "title": "Template Size",
                "type": "integer"
              },
              "total_variables": {
                "description": "Total extracted variables",
                "format": "uint",
                "minimum": 0,
                "title": "Total Variables",
                "type": "integer"
              }
            },
            "required": [
              "connected_variables",
              "default_variables",
              "missing_variables",
              "output_size",
              "template_size",
              "total_variables"
            ],
            "type": "object"
          }
        },
        "properties": {
          "all_variables": {
            "description": "All extracted variable names",
            "items": {
              "type": "string"
            },
            "title": "All Variables",
            "type": "array",
            "x-i18n-key": "nodes.utils.smart_var.outputs.all_variables"
          },
          "full_text": {
            "description": "Full text after variable substitution",
            "title": "Full Text",
            "type": "string",
            "x-i18n-key": "nodes.utils.smart_var.outputs.full_text"
          },
          "preview_content": {
            "description": "Formatted preview content",
            "title": "Preview Content",
            "type": "string",
            "x-i18n-key": "nodes.utils.smart_var.outputs.preview_content"
          },
          "selected_vars": {
            "additionalProperties": true,
            "description": "Picked variable key-value pairs",
            "title": "Picked Vars",
            "type": [
              "object",
              "null"
            ],
            "x-i18n-key": "nodes.utils.smart_var.outputs.selected_vars"
          },
          "statistics": {
            "allOf": [
              {
                "$ref": "#/definitions/VarStatistics"
              }
            ],
            "description": "Variable extraction statistics",
            "title": "Statistics",
            "x-i18n-key": "nodes.utils.smart_var.outputs.statistics"
          }
        },
        "required": [
          "all_variables",
          "full_text",
          "preview_content",
          "statistics"
        ],
        "title": "SmartVarOutput",
        "type": "object",
        "x-collapsed-visible": [
          "full_text"
        ],
        "x-field-order": [
          "full_text",
          "selected_vars",
          "all_variables",
          "preview_content",
          "statistics"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.utils.smart_var"
    },
    {
      "typeId": "utils/ui_controls_test",
      "name": "UI Controls Test",
      "category": "utils",
      "description": "For testing frontend form control rendering (select/switch/number/textarea/code/rich_text/slider, etc.)",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "UI 控件测试输入",
        "properties": {
          "code_snippet": {
            "default": "",
            "description": "Code editor (code_editor control)",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.utils.ui_controls_test.inputs.code_snippet"
          },
          "number_value": {
            "default": 0,
            "description": "Number input (number control)",
            "format": "int32",
            "maximum": 100,
            "minimum": 0,
            "title": "Number Value",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.utils.ui_controls_test.inputs.number_value"
          },
          "rich_text": {
            "default": "",
            "description": "Rich text editor (rich_text control)",
            "type": "string",
            "x-control": "rich-text",
            "x-i18n-key": "nodes.utils.ui_controls_test.inputs.rich_text"
          },
          "select_enum": {
            "default": "option_a",
            "description": "Dropdown enum select (select control)",
            "enum": [
              "option_a",
              "option_b",
              "option_c"
            ],
            "options": [
              {
                "label": "option_a",
                "value": "option_a"
              },
              {
                "label": "option_b",
                "value": "option_b"
              },
              {
                "label": "option_c",
                "value": "option_c"
              }
            ],
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.utils.ui_controls_test.inputs.select_enum"
          },
          "slider_value": {
            "default": 0,
            "description": "Slider value (slider control)",
            "format": "int32",
            "maximum": 100,
            "minimum": 0,
            "type": "integer",
            "x-control": "slider",
            "x-i18n-key": "nodes.utils.ui_controls_test.inputs.slider_value"
          },
          "text": {
            "description": "Plain string input (basic text field)",
            "title": "Text",
            "type": "string",
            "x-i18n-key": "nodes.utils.ui_controls_test.inputs.text"
          },
          "textarea_value": {
            "default": "",
            "description": "Multiline text input (textarea control)",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.utils.ui_controls_test.inputs.textarea_value"
          },
          "toggle": {
            "default": false,
            "description": "Boolean toggle (switch control)",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.utils.ui_controls_test.inputs.toggle"
          }
        },
        "required": [
          "text"
        ],
        "title": "UiControlsTestInput",
        "type": "object",
        "x-field-order": [
          "text",
          "select_enum",
          "toggle",
          "number_value",
          "slider_value",
          "textarea_value",
          "code_snippet",
          "rich_text"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "TestSelectEnum": {
            "description": "下拉枚举测试",
            "enum": [
              "option_a",
              "option_b",
              "option_c"
            ],
            "type": "string"
          }
        },
        "description": "UI 控件测试输出",
        "properties": {
          "numeric_sum": {
            "description": "Sum of number and slider values",
            "format": "int32",
            "title": "Numeric Sum",
            "type": "integer",
            "x-i18n-key": "nodes.utils.ui_controls_test.outputs.numeric_sum"
          },
          "selected_enum": {
            "allOf": [
              {
                "$ref": "#/definitions/TestSelectEnum"
              }
            ],
            "description": "Currently selected enum value",
            "title": "Selected Enum",
            "x-i18n-key": "nodes.utils.ui_controls_test.outputs.selected_enum"
          },
          "summary": {
            "description": "Summary string generated from combined inputs",
            "title": "Summary",
            "type": "string",
            "x-i18n-key": "nodes.utils.ui_controls_test.outputs.summary"
          },
          "toggle_on": {
            "description": "Boolean toggle state",
            "title": "Toggle On",
            "type": "boolean",
            "x-i18n-key": "nodes.utils.ui_controls_test.outputs.toggle_on"
          }
        },
        "required": [
          "numeric_sum",
          "selected_enum",
          "summary",
          "toggle_on"
        ],
        "title": "UiControlsTestOutput",
        "type": "object",
        "x-field-order": [
          "summary",
          "selected_enum",
          "numeric_sum",
          "toggle_on"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.utils.ui_controls_test"
    },
    {
      "typeId": "tools/subflow",
      "name": "Sub Workflow Tool",
      "category": "tools",
      "description": "Call other workflows as sub-workflows (supports file path or workflow ID)",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "async_execution": {
            "default": false,
            "description": "Whether to execute asynchronously; true returns immediately after start, false waits for completion",
            "title": "Async Execution",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.subflow.inputs.async_execution"
          },
          "call_stack": {
            "default": null,
            "description": "Call stack for detecting recursive calls (internal use)",
            "items": {
              "type": "string"
            },
            "title": "Call Stack",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.tools.subflow.inputs.call_stack"
          },
          "input_data": {
            "default": null,
            "description": "Input data passed to sub-workflow (optional)",
            "title": "Input Data",
            "x-i18n-key": "nodes.tools.subflow.inputs.input_data"
          },
          "max_parallelism": {
            "default": 10,
            "description": "Maximum number of parallel nodes",
            "format": "uint",
            "minimum": 0,
            "title": "Max Parallelism",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.subflow.inputs.max_parallelism"
          },
          "timeout_seconds": {
            "default": 300,
            "description": "Timeout in seconds",
            "format": "uint64",
            "minimum": 0,
            "title": "Timeout Seconds",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.subflow.inputs.timeout_seconds"
          },
          "workflow_path": {
            "description": "Workflow file path (JSON format) or workflow UUID",
            "maxLength": 4096,
            "minLength": 1,
            "title": "Workflow Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.subflow.inputs.workflow_path"
          }
        },
        "required": [
          "workflow_path"
        ],
        "title": "SubFlowInput",
        "type": "object",
        "x-field-order": [
          "workflow_path",
          "async_execution",
          "input_data",
          "call_stack",
          "timeout_seconds",
          "max_parallelism"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "elapsed_ms": {
            "description": "Execution time in milliseconds",
            "format": "uint64",
            "minimum": 0,
            "title": "Elapsed Ms",
            "type": "integer",
            "x-i18n-key": "nodes.tools.subflow.outputs.elapsed_ms"
          },
          "error": {
            "description": "Error message (if execution failed)",
            "title": "Error",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.subflow.outputs.error"
          },
          "output_data": {
            "description": "Sub-workflow output data",
            "title": "Output Data",
            "x-i18n-key": "nodes.tools.subflow.outputs.output_data"
          },
          "status": {
            "description": "Sub-workflow execution status",
            "title": "Status",
            "type": "string",
            "x-i18n-key": "nodes.tools.subflow.outputs.status"
          },
          "summary": {
            "description": "Execution result summary",
            "title": "Summary",
            "type": "string",
            "x-i18n-key": "nodes.tools.subflow.outputs.summary"
          }
        },
        "required": [
          "elapsed_ms",
          "output_data",
          "status",
          "summary"
        ],
        "title": "SubFlowOutput",
        "type": "object",
        "x-collapsed-visible": [
          "status",
          "summary"
        ],
        "x-field-order": [
          "status",
          "output_data",
          "elapsed_ms",
          "error",
          "summary"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.subflow"
    },
    {
      "typeId": "document/ops_hub",
      "name": "Document Operations Hub",
      "category": "document",
      "description": "Document operations hub node: control Agent document capabilities with toggle switches",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "allow_create": {
            "default": false,
            "description": "Whether to allow creating new documents (medium side-effect)",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.document.ops_hub.inputs.allow_create"
          },
          "allow_format": {
            "default": true,
            "description": "Whether to allow formatting documents (read-only)",
            "title": "Allow Format",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.document.ops_hub.inputs.allow_format"
          },
          "allow_query": {
            "default": true,
            "description": "Whether to allow querying documents (read-only)",
            "title": "Allow Query",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.document.ops_hub.inputs.allow_query"
          },
          "allow_update": {
            "default": false,
            "description": "Whether to allow updating document blocks (medium side-effect)",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.document.ops_hub.inputs.allow_update"
          },
          "config": {
            "additionalProperties": true,
            "description": "Unified config object (can input JSON text directly)",
            "title": "Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.document.ops_hub.inputs.config",
            "x-port": true
          },
          "document_id": {
            "description": "Document ID (common to most operations)",
            "title": "Document Id",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.ops_hub.inputs.document_id"
          },
          "operation": {
            "default": "",
            "description": "Operation type",
            "type": "string",
            "x-i18n-key": "nodes.document.ops_hub.inputs.operation"
          },
          "workspace_id": {
            "description": "Workspace ID (used by create operation, set by user on canvas)",
            "title": "Workspace Id",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.ops_hub.inputs.workspace_id"
          }
        },
        "required": [
          "allow_create",
          "allow_format",
          "allow_query",
          "allow_update"
        ],
        "title": "DocumentOpsHubInput",
        "type": "object",
        "x-collapsed-visible": [
          "workspace_id"
        ],
        "x-field-order": [
          "operation",
          "document_id",
          "config",
          "workspace_id",
          "allow_query",
          "allow_format",
          "allow_update",
          "allow_create"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "error": {
            "description": "Error message (operation prohibited or execution failed)",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.ops_hub.outputs.error"
          },
          "operation": {
            "description": "Actual operation type executed",
            "type": "string",
            "x-i18n-key": "nodes.document.ops_hub.outputs.operation"
          },
          "result": {
            "description": "Operation result (JSON-serialized sub-node output)",
            "x-i18n-key": "nodes.document.ops_hub.outputs.result"
          }
        },
        "required": [
          "operation",
          "result"
        ],
        "title": "DocumentOpsHubOutput",
        "type": "object",
        "x-collapsed-visible": [
          "operation"
        ],
        "x-field-order": [
          "operation",
          "error",
          "result"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.document.ops_hub"
    },
    {
      "typeId": "chat/save_reply",
      "name": "Save LLM Reply",
      "category": "chat",
      "description": "Persist LLM-output assistant messages and build clean next-round history via structured TurnRecord (idempotent)",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Chat 回复持久化节点输入",
        "properties": {
          "clean_history_json": {
            "default": "",
            "description": "Clean history before appending current user message (JSON format), from chat/memory.clean_history_json",
            "type": "string",
            "x-i18n-key": "nodes.chat.save_reply.inputs.clean_history_json",
            "x-port": true
          },
          "context": {
            "additionalProperties": true,
            "description": "Context output from agent/react (contains conversation history and this turn's reply)",
            "title": "Agent Context",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.chat.save_reply.inputs.context",
            "x-port": true
          },
          "conversation_id": {
            "default": null,
            "description": "Current conversation ID (from chat/memory.conversation_id), skipped when None in Memory mode",
            "type": "string",
            "x-i18n-key": "nodes.chat.save_reply.inputs.conversation_id",
            "x-port": true
          },
          "reply_id": {
            "default": null,
            "description": "Manually specified idempotent deduplication key (optional)",
            "title": "Reply ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.chat.save_reply.inputs.reply_id"
          },
          "trace_key": {
            "default": null,
            "description": "Trace retrieval key, from chat/write_trace.trace_key (optional)",
            "type": "string",
            "x-i18n-key": "nodes.chat.save_reply.inputs.trace_key",
            "x-port": true
          },
          "user_message": {
            "default": null,
            "description": "This turn's user input text (from chat/input.user_message), this value takes priority",
            "type": "string",
            "x-i18n-key": "nodes.chat.save_reply.inputs.user_message",
            "x-port": true
          },
          "user_message_rich": {
            "additionalProperties": true,
            "default": null,
            "description": "Structured user message with multimodal parts",
            "type": "object",
            "x-i18n-key": "nodes.chat.save_reply.inputs.user_message_rich",
            "x-port": true
          },
          "workspace_id": {
            "default": null,
            "description": "Workspace ID (optional), used to verify the conversation belongs to the expected workspace before writing",
            "type": "string",
            "x-i18n-key": "nodes.chat.save_reply.inputs.workspace_id",
            "x-port": true
          }
        },
        "required": [
          "context"
        ],
        "title": "ChatSaveReplyInput",
        "type": "object",
        "x-field-order": [
          "context",
          "user_message",
          "user_message_rich",
          "clean_history_json",
          "trace_key",
          "conversation_id",
          "workspace_id",
          "reply_id"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Chat 回复持久化节点输出",
        "properties": {
          "context": {
            "additionalProperties": true,
            "description": "AgentContext containing clean history, connectable directly to chat/output",
            "title": "Agent Context",
            "type": "object",
            "x-i18n-key": "nodes.chat.save_reply.outputs.context",
            "x-port": true
          },
          "db_persisted": {
            "description": "Whether assistant reply was successfully persisted to database (always false in Memory mode, does not affect TurnRecord memory preservation)",
            "title": "Db Persisted",
            "type": "boolean",
            "x-i18n-key": "nodes.chat.save_reply.outputs.db_persisted"
          }
        },
        "required": [
          "context",
          "db_persisted"
        ],
        "title": "ChatSaveReplyOutput",
        "type": "object",
        "x-collapsed-visible": [],
        "x-field-order": [
          "context",
          "db_persisted"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.chat.save_reply"
    },
    {
      "typeId": "ai/llm_config",
      "name": "LLM Config",
      "category": "agent",
      "description": "Select connected LLM model, output complete configuration",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "LLM 配置节点输入",
        "properties": {
          "frequency_penalty": {
            "default": 0,
            "description": "Reduce likelihood of repeating the same line (-2.0 to 2.0)",
            "format": "float",
            "maximum": 2,
            "minimum": -2,
            "step": "0.1",
            "step-number": 0.1,
            "title": "Frequency Penalty",
            "type": "number",
            "x-control": "slider",
            "x-i18n-key": "nodes.ai.llm_config.inputs.frequency_penalty",
            "x-step": "0.1"
          },
          "json_mode": {
            "default": false,
            "description": "Inject response_format: json_object (for weaker/open-source models, reduces non-JSON text; no system-level validation)",
            "title": "JSON Output Mode",
            "type": "boolean",
            "x-i18n-key": "nodes.ai.llm_config.inputs.json_mode"
          },
          "max_tokens": {
            "default": 5000,
            "description": "Maximum number of tokens to generate (default 5000)",
            "format": "uint32",
            "minimum": 0,
            "title": "Max Tokens",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.ai.llm_config.inputs.max_tokens"
          },
          "model": {
            "description": "Select a connected LLM model",
            "title": "Model",
            "type": "string",
            "x-allow-custom": true,
            "x-control": "llm-model-select",
            "x-i18n-key": "nodes.ai.llm_config.inputs.model",
            "x-model-name-excludes": [
              "embed",
              "embedding",
              "rerank",
              "reranker"
            ],
            "x-models-api": "/api/v1/llm/providers"
          },
          "model_override": {
            "default": null,
            "description": "Model override (format: credential_id::model_name, takes priority over model)",
            "title": "Model Override",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.ai.llm_config.inputs.model_override"
          },
          "presence_penalty": {
            "default": 0,
            "description": "Encourage the model to discuss new topics (-2.0 to 2.0)",
            "format": "float",
            "maximum": 2,
            "minimum": -2,
            "step": "0.1",
            "step-number": 0.1,
            "title": "Presence Penalty",
            "type": "number",
            "x-control": "slider",
            "x-i18n-key": "nodes.ai.llm_config.inputs.presence_penalty",
            "x-step": "0.1"
          },
          "stream": {
            "default": true,
            "description": "Enable real-time streaming of results",
            "title": "Streaming",
            "type": "boolean",
            "x-i18n-key": "nodes.ai.llm_config.inputs.stream"
          },
          "temperature": {
            "default": 0.699999988079071,
            "description": "Controls randomness of generation, higher values are more random (0.0 - 2.0)",
            "format": "float",
            "maximum": 2,
            "minimum": 0,
            "step": "0.1",
            "step-number": 0.1,
            "title": "Temperature",
            "type": "number",
            "x-control": "slider",
            "x-i18n-key": "nodes.ai.llm_config.inputs.temperature",
            "x-step": "0.1"
          },
          "timeout_secs": {
            "default": 60,
            "description": "API request timeout (1-600 seconds)",
            "format": "uint32",
            "maximum": 600,
            "minimum": 1,
            "title": "Timeout (seconds)",
            "type": "integer",
            "x-i18n-key": "nodes.ai.llm_config.inputs.timeout_secs"
          },
          "top_p": {
            "default": 1,
            "description": "Nucleus sampling threshold (0.0 - 1.0)",
            "format": "float",
            "maximum": 1,
            "minimum": 0,
            "step": "0.1",
            "step-number": 0.1,
            "title": "Top P",
            "type": "number",
            "x-control": "slider",
            "x-i18n-key": "nodes.ai.llm_config.inputs.top_p",
            "x-step": "0.1"
          }
        },
        "required": [
          "model"
        ],
        "title": "LlmConfigInput",
        "type": "object",
        "x-field-order": [
          "model",
          "model_override",
          "temperature",
          "max_tokens",
          "top_p",
          "frequency_penalty",
          "presence_penalty",
          "stream",
          "timeout_secs",
          "json_mode"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "LLM 配置节点输出 - 只有一个完整配置对象",
        "properties": {
          "llm_config": {
            "additionalProperties": true,
            "description": "Complete LLM configuration",
            "title": "LLM Config",
            "type": "object",
            "x-i18n-key": "nodes.ai.llm_config.outputs.llm_config",
            "x-port": true
          }
        },
        "required": [
          "llm_config"
        ],
        "title": "LlmConfigOutput",
        "type": "object",
        "x-field-order": [
          "llm_config"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.ai.llm_config"
    },
    {
      "typeId": "table/build_llm_context",
      "name": "Build Table LLM Context",
      "category": "table",
      "description": "Build context information for LLM table editing",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input for TableBuildLlmContextNode",
        "properties": {
          "format": {
            "default": "json",
            "description": "Output format: \"json\", \"markdown\", or \"csv\".",
            "type": "string",
            "x-i18n-key": "nodes.table.build_llm_context.inputs.format"
          },
          "instruction": {
            "description": "User's editing instruction/request.",
            "type": "string",
            "x-i18n-key": "nodes.table.build_llm_context.inputs.instruction"
          },
          "max_records": {
            "default": 100,
            "description": "Maximum records to include in context (0 = unlimited).",
            "format": "uint",
            "minimum": 0,
            "title": "Max Records",
            "type": "integer",
            "x-i18n-key": "nodes.table.build_llm_context.inputs.max_records"
          },
          "selected_record_ids": {
            "default": null,
            "description": "Optional list of selected record IDs. If provided, only these records will be included in the context.",
            "items": {
              "type": "string"
            },
            "title": "Selected Record Ids",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.table.build_llm_context.inputs.selected_record_ids"
          },
          "table_id": {
            "description": "Table ID to build context for.",
            "title": "Table Id",
            "type": "string",
            "x-i18n-key": "nodes.table.build_llm_context.inputs.table_id"
          }
        },
        "required": [
          "instruction",
          "table_id"
        ],
        "title": "TableBuildLlmContextInput",
        "type": "object",
        "x-field-order": [
          "table_id",
          "selected_record_ids",
          "instruction",
          "format",
          "max_records"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Output from TableBuildLlmContextNode",
        "properties": {
          "agent_context": {
            "additionalProperties": true,
            "description": "AgentContext port (can be directly connected to Agent node's context input)",
            "title": "Agent Context",
            "type": "object",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.agent_context",
            "x-port": true
          },
          "column_count": {
            "description": "Number of columns.",
            "format": "uint",
            "minimum": 0,
            "type": "integer",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.column_count"
          },
          "error": {
            "description": "Error message if building failed.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.table.build_llm_context.outputs.error"
          },
          "llm_context": {
            "description": "Integrated LLM context as JSON string. Connect this to ReAct agent's `task` input.",
            "title": "Llm Context",
            "type": "string",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.llm_context"
          },
          "records_included": {
            "description": "Number of records included.",
            "format": "uint",
            "minimum": 0,
            "type": "integer",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.records_included"
          },
          "success": {
            "description": "Whether context building was successful.",
            "type": "boolean",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.success"
          },
          "system_prompt": {
            "description": "System prompt for LLM.",
            "title": "System Prompt",
            "type": "string",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.system_prompt"
          },
          "table_context": {
            "description": "Table context (formatted table data).",
            "title": "Table Context",
            "type": "string",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.table_context"
          },
          "table_id": {
            "description": "Table ID.",
            "title": "Table Id",
            "type": "string",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.table_id"
          },
          "table_name": {
            "description": "Table name.",
            "title": "Table Name",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.table.build_llm_context.outputs.table_name"
          },
          "tools_json": {
            "description": "Tool definitions JSON for LLM function calling.",
            "title": "Tools Json",
            "type": "string",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.tools_json"
          },
          "user_prompt": {
            "description": "User instruction (formatted).",
            "title": "User Prompt",
            "type": "string",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.user_prompt"
          },
          "warnings": {
            "description": "Warnings generated during context building.",
            "items": {
              "type": "string"
            },
            "type": "array",
            "x-i18n-key": "nodes.table.build_llm_context.outputs.warnings"
          }
        },
        "required": [
          "agent_context",
          "column_count",
          "llm_context",
          "records_included",
          "success",
          "system_prompt",
          "table_context",
          "table_id",
          "tools_json",
          "user_prompt"
        ],
        "title": "TableBuildLlmContextOutput",
        "type": "object",
        "x-collapsed-visible": [
          "agent_context"
        ],
        "x-field-order": [
          "success",
          "table_id",
          "table_name",
          "system_prompt",
          "table_context",
          "user_prompt",
          "tools_json",
          "llm_context",
          "agent_context",
          "records_included",
          "column_count",
          "error",
          "warnings"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.table.build_llm_context"
    },
    {
      "typeId": "tools/file_info",
      "name": "File Info",
      "category": "tools",
      "description": "Get file or directory metadata (size, line count, modification time, binary or not, etc.) without reading file content.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "path": {
            "description": "Absolute path of file or directory",
            "title": "Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.file_info.inputs.path"
          }
        },
        "required": [
          "path"
        ],
        "title": "FileInfoInput",
        "type": "object"
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "EntryType": {
            "description": "条目类型",
            "enum": [
              "file",
              "dir",
              "symlink"
            ],
            "type": "string"
          }
        },
        "properties": {
          "created": {
            "description": "创建时间(ISO 8601,部分 OS 不支持则为 None)",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.file_info.outputs.created"
          },
          "entry_type": {
            "anyOf": [
              {
                "$ref": "#/definitions/EntryType"
              },
              {
                "type": "null"
              }
            ],
            "description": "条目类型(File / Dir / Symlink)",
            "title": "Entry Type",
            "x-i18n-key": "nodes.tools.file_info.outputs.entry_type"
          },
          "error": {
            "description": "错误信息",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.file_info.outputs.error"
          },
          "exists": {
            "description": "路径是否存在",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.file_info.outputs.exists"
          },
          "is_binary": {
            "description": "是否为二进制文件",
            "title": "Is Binary",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.file_info.outputs.is_binary"
          },
          "is_readable": {
            "description": "当前进程是否有读取权限",
            "title": "Is Readable",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.file_info.outputs.is_readable"
          },
          "is_writable": {
            "description": "当前进程是否有写入权限",
            "title": "Is Writable",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.file_info.outputs.is_writable"
          },
          "metadata": {
            "description": "所有元信息的聚合摘要(适合直接传给 LLM / Preview 节点)",
            "type": "string",
            "x-i18n-key": "nodes.tools.file_info.outputs.metadata"
          },
          "mime_type": {
            "description": "MIME 类型推断(如 \"text/x-rust\", \"text/plain\")",
            "title": "Mime Type",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.file_info.outputs.mime_type"
          },
          "modified": {
            "description": "修改时间(ISO 8601)",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.file_info.outputs.modified"
          },
          "path": {
            "description": "规范化后的绝对路径",
            "type": "string",
            "x-i18n-key": "nodes.tools.file_info.outputs.path"
          },
          "size_bytes": {
            "description": "文件大小(字节);目录为 None",
            "format": "uint64",
            "minimum": 0,
            "title": "Size Bytes",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.file_info.outputs.size_bytes"
          },
          "total_lines": {
            "description": "文本文件总行数;二进制文件或目录为 None",
            "format": "uint32",
            "minimum": 0,
            "title": "Total Lines",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.file_info.outputs.total_lines"
          }
        },
        "required": [
          "exists",
          "is_binary",
          "is_readable",
          "is_writable",
          "metadata",
          "path"
        ],
        "title": "FileInfoOutput",
        "type": "object",
        "x-collapsed-visible": [
          "metadata"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.file_info"
    },
    {
      "typeId": "ai/embedding_config",
      "name": "Embedding Config",
      "category": "agent",
      "description": "Select connected Embedding model, output complete configuration",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Embedding 配置节点输入",
        "properties": {
          "batch_size": {
            "default": null,
            "description": "批量处理大小",
            "title": "Batch Size",
            "type": "integer",
            "x-allow-custom": true,
            "x-control": "select",
            "x-i18n-key": "nodes.ai.embedding_config.inputs.batch_size",
            "x-options": [
              {
                "label": "16",
                "value": 16
              },
              {
                "label": "32",
                "value": 32
              },
              {
                "label": "64",
                "value": 64
              },
              {
                "label": "128",
                "value": 128
              },
              {
                "label": "256",
                "value": 256
              }
            ]
          },
          "dimension": {
            "default": 1024,
            "description": "向量维度",
            "title": "Vector Dimensions",
            "type": "integer",
            "x-allow-custom": true,
            "x-control": "select",
            "x-default": 1024,
            "x-i18n-key": "nodes.ai.embedding_config.inputs.dimension",
            "x-options": [
              {
                "label": "384",
                "value": 384
              },
              {
                "label": "768",
                "value": 768
              },
              {
                "label": "1024",
                "value": 1024
              },
              {
                "label": "1536",
                "value": 1536
              },
              {
                "label": "3072",
                "value": 3072
              }
            ]
          },
          "embedding_model": {
            "description": "Select a connected Embedding model. Supports credential_id::model_name or model_name (requires CHENG_DEFAULT_EMBEDDING_CREDENTIAL_ID)",
            "title": "Embedding Model",
            "type": "string",
            "x-allow-custom": true,
            "x-control": "llm-model-select",
            "x-i18n-key": "nodes.ai.embedding_config.inputs.embedding_model",
            "x-model-name-includes": [
              "embed",
              "embedding"
            ],
            "x-models-api": "/api/v1/llm/providers"
          },
          "reranker_model": {
            "default": null,
            "description": "Select a reranker model (optional, for post-processing optimization)",
            "title": "Reranker Model",
            "type": "string",
            "x-allow-custom": true,
            "x-control": "llm-model-select",
            "x-i18n-key": "nodes.ai.embedding_config.inputs.reranker_model",
            "x-model-name-includes": [
              "rerank",
              "reranker"
            ],
            "x-models-api": "/api/v1/llm/providers"
          },
          "reranker_top_k": {
            "default": null,
            "description": "Reranker Top K",
            "title": "Reranker Top K",
            "type": "integer",
            "x-allow-custom": true,
            "x-control": "select",
            "x-default": 3,
            "x-i18n-key": "nodes.ai.embedding_config.inputs.reranker_top_k",
            "x-options": [
              {
                "label": "3",
                "value": 3
              },
              {
                "label": "5",
                "value": 5
              },
              {
                "label": "10",
                "value": 10
              },
              {
                "label": "20",
                "value": 20
              }
            ]
          }
        },
        "required": [
          "embedding_model"
        ],
        "title": "EmbeddingConfigInput",
        "type": "object",
        "x-field-order": [
          "embedding_model",
          "dimension",
          "batch_size",
          "reranker_model",
          "reranker_top_k"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Embedding 配置节点输出",
        "properties": {
          "embedding_config": {
            "additionalProperties": true,
            "description": "Complete Embedding configuration",
            "title": "Embedding Config",
            "type": "object",
            "x-i18n-key": "nodes.ai.embedding_config.outputs.embedding_config",
            "x-port": true
          },
          "reranker_config": {
            "additionalProperties": true,
            "description": "Reranker configuration (if a reranker model is configured)",
            "title": "Reranker Config",
            "type": "object",
            "x-i18n-key": "nodes.ai.embedding_config.outputs.reranker_config",
            "x-port": true
          }
        },
        "required": [
          "embedding_config",
          "reranker_config"
        ],
        "title": "EmbeddingConfigOutput",
        "type": "object",
        "x-field-order": [
          "embedding_config",
          "reranker_config"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.ai.embedding_config"
    },
    {
      "typeId": "tools/ssh",
      "name": "SSH Executor",
      "category": "tools",
      "description": "Execute commands on remote hosts via SSH with a built-in approval gate. Risk-classifies commands, enforces read-only policy, and surfaces 4 distinct rejection reasons (rejected/skipped/timed_out/policy_denied) so agents can replan correctly.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "approval_required_at_or_above": {
            "default": "medium",
            "description": "Risk threshold for triggering the approval gate (medium by default)",
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "options": [
              {
                "label": "low",
                "value": "low"
              },
              {
                "label": "medium",
                "value": "medium"
              },
              {
                "label": "high",
                "value": "high"
              },
              {
                "label": "critical",
                "value": "critical"
              }
            ],
            "title": "Approval Required At Or Above",
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.tools.ssh.inputs.approval_required_at_or_above"
          },
          "approval_timeout_secs": {
            "default": 300,
            "description": "Seconds to wait for the user's decision before timing out (default 300)",
            "format": "uint64",
            "maximum": 86400,
            "minimum": 5,
            "title": "Approval Timeout (s)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.ssh.inputs.approval_timeout_secs"
          },
          "command": {
            "default": "",
            "description": "Command to execute on the remote host",
            "maxLength": 65536,
            "title": "Command",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.tools.ssh.inputs.command"
          },
          "credential_id": {
            "default": null,
            "description": "SSH credential — private key or password (resolved via CredentialRepository)",
            "title": "Credential",
            "type": "string",
            "x-control": "credential-select",
            "x-credential-providers": [
              "ssh",
              "ssh_password"
            ],
            "x-i18n-key": "nodes.tools.ssh.inputs.credential_id"
          },
          "host": {
            "description": "Remote host (hostname or IP)",
            "title": "Host",
            "type": "string",
            "x-i18n-key": "nodes.tools.ssh.inputs.host"
          },
          "port": {
            "default": 22,
            "description": "Remote SSH port",
            "format": "uint64",
            "maximum": 65535,
            "minimum": 1,
            "title": "Port",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.ssh.inputs.port"
          },
          "read_only_mode": {
            "default": false,
            "description": "Hard policy: when enabled, any non-readonly command is denied without going through approval",
            "title": "Read-only Mode (hard policy)",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.ssh.inputs.read_only_mode"
          },
          "strict_host_key_checking": {
            "default": true,
            "description": "TOFU: first-connect host key prompts user approval; subsequent connects use the trusted key. Disable only for ad-hoc testing.",
            "title": "Strict Host Key Checking",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.ssh.inputs.strict_host_key_checking"
          },
          "timeout_ms": {
            "default": 30000,
            "description": "Per-command execution timeout in milliseconds",
            "format": "uint64",
            "maximum": 600000,
            "minimum": 100,
            "title": "Timeout (ms)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.ssh.inputs.timeout_ms"
          },
          "username": {
            "default": null,
            "description": "SSH login username (defaults to root)",
            "title": "Username",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.ssh.inputs.username"
          },
          "working_dir": {
            "default": null,
            "description": "Optional cwd before executing the command",
            "title": "Working Directory",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.ssh.inputs.working_dir"
          }
        },
        "required": [
          "host"
        ],
        "title": "SshInput",
        "type": "object",
        "x-collapsed-visible": [
          "host",
          "command"
        ],
        "x-field-order": [
          "host",
          "port",
          "username",
          "credential_id",
          "command",
          "working_dir",
          "timeout_ms",
          "strict_host_key_checking",
          "read_only_mode",
          "approval_required_at_or_above",
          "approval_timeout_secs"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "approval_request_id": {
            "description": "UUID matching the approval bus event",
            "title": "Approval Request Id",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.ssh.outputs.approval_request_id"
          },
          "command": {
            "description": "Command echoed back for traceability",
            "title": "Command",
            "type": "string",
            "x-i18n-key": "nodes.tools.ssh.outputs.command"
          },
          "duration_ms": {
            "description": "Wall-clock execution time",
            "format": "uint64",
            "minimum": 0,
            "title": "Duration (ms)",
            "type": "integer",
            "x-i18n-key": "nodes.tools.ssh.outputs.duration_ms"
          },
          "exit_code": {
            "description": "Remote process exit code",
            "format": "int32",
            "title": "Exit Code",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.ssh.outputs.exit_code"
          },
          "host": {
            "description": "Target host echoed back for traceability",
            "title": "Host",
            "type": "string",
            "x-i18n-key": "nodes.tools.ssh.outputs.host"
          },
          "observation": {
            "description": "Agent-facing observation text with [APPROVAL_*] prefixes",
            "title": "Observation",
            "type": "string",
            "x-i18n-key": "nodes.tools.ssh.outputs.observation"
          },
          "reason": {
            "description": "Reason text from user or policy",
            "title": "Reason",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.ssh.outputs.reason"
          },
          "rejection_type": {
            "description": "Distinguishes execute / approval / policy outcomes",
            "title": "Rejection Type",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.ssh.outputs.rejection_type"
          },
          "risk_level": {
            "description": "Classified risk for this command",
            "title": "Risk Level",
            "type": "string",
            "x-i18n-key": "nodes.tools.ssh.outputs.risk_level"
          },
          "stderr": {
            "description": "Captured stderr",
            "title": "Stderr",
            "type": "string",
            "x-i18n-key": "nodes.tools.ssh.outputs.stderr"
          },
          "stdout": {
            "description": "Captured stdout",
            "title": "Stdout",
            "type": "string",
            "x-i18n-key": "nodes.tools.ssh.outputs.stdout"
          },
          "success": {
            "description": "True iff the command executed and returned 0",
            "title": "Success",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.ssh.outputs.success"
          }
        },
        "required": [
          "command",
          "duration_ms",
          "host",
          "observation",
          "risk_level",
          "stderr",
          "stdout",
          "success"
        ],
        "title": "SshOutput",
        "type": "object",
        "x-collapsed-visible": [
          "observation"
        ],
        "x-field-order": [
          "success",
          "exit_code",
          "stdout",
          "stderr",
          "duration_ms",
          "host",
          "command",
          "risk_level",
          "rejection_type",
          "reason",
          "approval_request_id",
          "observation"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.ssh"
    },
    {
      "typeId": "tools/write_file",
      "name": "Write File",
      "category": "tools",
      "description": "Create new file or overwrite/append existing file. Uses atomic write (temp file + rename) to prevent file corruption from interrupted writes.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "append": {
            "default": false,
            "description": "Append mode (takes priority over overwrite), default false",
            "title": "Append",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.write_file.inputs.append"
          },
          "content": {
            "description": "File content to write (UTF-8)",
            "title": "Content",
            "type": "string",
            "x-i18n-key": "nodes.tools.write_file.inputs.content"
          },
          "create_dirs": {
            "default": true,
            "description": "Whether to automatically create parent directories, default true",
            "title": "Create Dirs",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.write_file.inputs.create_dirs"
          },
          "file_path": {
            "description": "Absolute file path to write",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.write_file.inputs.file_path"
          },
          "overwrite": {
            "default": false,
            "description": "Whether to allow overwriting existing file, default false",
            "title": "Overwrite",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.write_file.inputs.overwrite"
          }
        },
        "required": [
          "content",
          "file_path"
        ],
        "title": "WriteFileInput",
        "type": "object"
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "bytes_written": {
            "description": "写入字节数",
            "format": "uint64",
            "minimum": 0,
            "title": "Bytes Written",
            "type": "integer",
            "x-i18n-key": "nodes.tools.write_file.outputs.bytes_written"
          },
          "created": {
            "description": "true=新建文件,false=覆写或追加",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.write_file.outputs.created"
          },
          "error": {
            "description": "错误信息",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.write_file.outputs.error"
          },
          "file_path": {
            "description": "实际写入的规范路径",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.write_file.outputs.file_path"
          },
          "summary": {
            "description": "写入结果摘要(适合直接传给 LLM / Preview 节点)",
            "type": "string",
            "x-i18n-key": "nodes.tools.write_file.outputs.summary"
          }
        },
        "required": [
          "bytes_written",
          "created",
          "file_path",
          "summary"
        ],
        "title": "WriteFileOutput",
        "type": "object",
        "x-collapsed-visible": [
          "file_path",
          "summary"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.write_file"
    },
    {
      "typeId": "table/query",
      "name": "Query Table",
      "category": "table",
      "description": "Get table data, including column definitions and records",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input for TableQueryNode",
        "properties": {
          "include_schema": {
            "default": true,
            "description": "Whether to include column definitions (default: true).",
            "title": "Include Schema",
            "type": "boolean",
            "x-i18n-key": "nodes.table.query.inputs.include_schema"
          },
          "page": {
            "default": 1,
            "description": "Page number for pagination (1-based, default: 1).",
            "format": "uint32",
            "minimum": 0,
            "type": "integer",
            "x-i18n-key": "nodes.table.query.inputs.page"
          },
          "page_size": {
            "default": 100,
            "description": "Number of records per page (default: 100, max: 1000).",
            "format": "uint32",
            "minimum": 0,
            "title": "Page Size",
            "type": "integer",
            "x-i18n-key": "nodes.table.query.inputs.page_size"
          },
          "record_ids": {
            "default": null,
            "description": "Optional list of specific record IDs to fetch. If not provided, fetches all records (paginated).",
            "items": {
              "type": "string"
            },
            "title": "Record Ids",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.table.query.inputs.record_ids"
          },
          "table_id": {
            "description": "ID of the table to query.",
            "title": "Table Id",
            "type": "string",
            "x-i18n-key": "nodes.table.query.inputs.table_id"
          },
          "workspace_id": {
            "default": null,
            "description": "Select workspace to validate table belongs to",
            "title": "Workspace Id",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces?limit=200",
            "x-cache-key": "static_select:/api/v1/workspaces?limit=200",
            "x-control": "dynamic-select",
            "x-i18n-key": "nodes.table.query.inputs.workspace_id"
          }
        },
        "required": [
          "table_id"
        ],
        "title": "TableQueryInput",
        "type": "object",
        "x-field-order": [
          "workspace_id",
          "table_id",
          "record_ids",
          "include_schema",
          "page",
          "page_size"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "ColumnInfo": {
            "description": "Column information in output",
            "properties": {
              "column_type": {
                "description": "Column type (text, number, select, date, checkbox).",
                "type": "string"
              },
              "config": {
                "description": "Column configuration (e.g., select options)."
              },
              "id": {
                "description": "Column ID.",
                "type": "string"
              },
              "name": {
                "description": "Column name.",
                "type": "string"
              },
              "order_index": {
                "description": "Order index for display.",
                "format": "double",
                "type": "number"
              }
            },
            "required": [
              "column_type",
              "id",
              "name",
              "order_index"
            ],
            "type": "object"
          },
          "RecordInfo": {
            "description": "Record information in output",
            "properties": {
              "created_at": {
                "description": "Created timestamp.",
                "type": "string"
              },
              "data": {
                "description": "Record data as key-value pairs (column_id -> cell_value)."
              },
              "id": {
                "description": "Record ID.",
                "type": "string"
              },
              "order_index": {
                "description": "Order index for display.",
                "format": "double",
                "type": "number"
              },
              "updated_at": {
                "description": "Updated timestamp.",
                "type": "string"
              }
            },
            "required": [
              "created_at",
              "data",
              "id",
              "order_index",
              "updated_at"
            ],
            "type": "object"
          },
          "TableInfo": {
            "description": "Table metadata in output",
            "properties": {
              "created_at": {
                "description": "Created timestamp.",
                "type": "string"
              },
              "description": {
                "description": "Table description.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "id": {
                "description": "Table ID.",
                "type": "string"
              },
              "name": {
                "description": "Table name.",
                "type": "string"
              },
              "updated_at": {
                "description": "Updated timestamp.",
                "type": "string"
              },
              "workspace_id": {
                "description": "Workspace ID.",
                "type": "string"
              }
            },
            "required": [
              "created_at",
              "id",
              "name",
              "updated_at",
              "workspace_id"
            ],
            "type": "object"
          }
        },
        "description": "Output from TableQueryNode",
        "properties": {
          "agent_context": {
            "additionalProperties": true,
            "description": "AgentContext port (can be directly connected to Agent node's context input)",
            "title": "Agent Context",
            "type": "object",
            "x-i18n-key": "nodes.table.query.outputs.agent_context",
            "x-port": true
          },
          "columns": {
            "description": "Column definitions (if include_schema=true).",
            "items": {
              "$ref": "#/definitions/ColumnInfo"
            },
            "type": "array",
            "x-i18n-key": "nodes.table.query.outputs.columns"
          },
          "error": {
            "description": "Error message if query failed.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.table.query.outputs.error"
          },
          "found": {
            "description": "Whether the table was found.",
            "type": "boolean",
            "x-i18n-key": "nodes.table.query.outputs.found"
          },
          "markdown": {
            "description": "Markdown formatted table (columns + records), suitable for preview node.",
            "type": "string",
            "x-i18n-key": "nodes.table.query.outputs.markdown"
          },
          "page": {
            "description": "Current page number.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer",
            "x-i18n-key": "nodes.table.query.outputs.page"
          },
          "records": {
            "description": "Records data.",
            "items": {
              "$ref": "#/definitions/RecordInfo"
            },
            "type": "array",
            "x-i18n-key": "nodes.table.query.outputs.records"
          },
          "success": {
            "description": "Whether the query was successful.",
            "type": "boolean",
            "x-i18n-key": "nodes.table.query.outputs.success"
          },
          "table": {
            "anyOf": [
              {
                "$ref": "#/definitions/TableInfo"
              },
              {
                "type": "null"
              }
            ],
            "description": "Table metadata (if found).",
            "x-i18n-key": "nodes.table.query.outputs.table"
          },
          "total_pages": {
            "description": "Total number of pages.",
            "format": "uint32",
            "minimum": 0,
            "title": "Total Pages",
            "type": "integer",
            "x-i18n-key": "nodes.table.query.outputs.total_pages"
          },
          "total_records": {
            "description": "Total number of records in the table.",
            "format": "uint64",
            "minimum": 0,
            "title": "Total Records",
            "type": "integer",
            "x-i18n-key": "nodes.table.query.outputs.total_records"
          }
        },
        "required": [
          "agent_context",
          "columns",
          "found",
          "markdown",
          "page",
          "records",
          "success",
          "total_pages",
          "total_records"
        ],
        "title": "TableQueryOutput",
        "type": "object",
        "x-collapsed-visible": [
          "markdown",
          "agent_context"
        ],
        "x-field-order": [
          "success",
          "found",
          "table",
          "columns",
          "records",
          "total_records",
          "page",
          "total_pages",
          "error",
          "markdown",
          "agent_context"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.table.query"
    },
    {
      "typeId": "rag/kb_manager",
      "name": "Knowledge Base Manager",
      "category": "rag",
      "description": "Manage knowledge bases (list, delete, view details)",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Knowledge Base Manager input",
        "properties": {
          "kb_id": {
            "default": null,
            "description": "Target knowledge base (required for delete and info operations)",
            "title": "Knowledge Base",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces/{workspace_id}/knowledge-bases?limit=200",
            "x-control": "dynamic-select",
            "x-depends-on": "workspace_id",
            "x-i18n-key": "nodes.rag.kb_manager.inputs.kb_id"
          },
          "operation": {
            "default": "list",
            "description": "Operation to perform",
            "title": "Operation",
            "type": "string",
            "x-control": "select",
            "x-default": "list",
            "x-i18n-key": "nodes.rag.kb_manager.inputs.operation",
            "x-options": [
              {
                "description": "List all knowledge bases",
                "label": "List All",
                "value": "list"
              },
              {
                "description": "Delete specified knowledge base",
                "label": "Delete",
                "value": "delete"
              },
              {
                "description": "Get detailed knowledge base information",
                "label": "View Info",
                "value": "info"
              }
            ]
          },
          "qdrant_config": {
            "additionalProperties": true,
            "description": "Qdrant configuration object from config node",
            "title": "Qdrant Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.rag.kb_manager.inputs.qdrant_config",
            "x-port": true
          },
          "workspace_id": {
            "description": "Target workspace (required for all operations)",
            "title": "Workspace ID",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces?limit=200",
            "x-cache-key": "static_select:/api/v1/workspaces?limit=200",
            "x-control": "dynamic-select",
            "x-i18n-key": "nodes.rag.kb_manager.inputs.workspace_id"
          }
        },
        "required": [
          "qdrant_config",
          "workspace_id"
        ],
        "title": "KbManagerInput",
        "type": "object",
        "x-collapsed-visible": [
          "workspace_id",
          "qdrant_config",
          "operation",
          "kb_id"
        ],
        "x-field-order": [
          "workspace_id",
          "qdrant_config",
          "operation",
          "kb_id"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "CollectionInfoOutput": {
            "description": "Collection info for output",
            "properties": {
              "indexed_points_count": {
                "description": "Number of indexed document chunks",
                "format": "uint64",
                "minimum": 0,
                "title": "Indexed Points Count",
                "type": "integer"
              },
              "name": {
                "description": "Knowledge base name",
                "title": "Name",
                "type": "string"
              },
              "points_count": {
                "description": "Number of document chunks",
                "format": "uint64",
                "minimum": 0,
                "title": "Points Count",
                "type": "integer"
              },
              "status": {
                "description": "Collection status",
                "title": "Status",
                "type": "string"
              },
              "vectors": {
                "description": "Vector configurations",
                "items": {
                  "type": "string"
                },
                "title": "Vectors",
                "type": "array"
              }
            },
            "required": [
              "indexed_points_count",
              "name",
              "points_count",
              "status",
              "vectors"
            ],
            "type": "object"
          }
        },
        "description": "Knowledge Base Manager output",
        "properties": {
          "collection_info": {
            "anyOf": [
              {
                "$ref": "#/definitions/CollectionInfoOutput"
              },
              {
                "type": "null"
              }
            ],
            "description": "Knowledge base details",
            "title": "Collection Info",
            "x-i18n-key": "nodes.rag.kb_manager.outputs.collection_info"
          },
          "collections": {
            "description": "List of knowledge bases",
            "items": {
              "type": "string"
            },
            "title": "Collections",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.rag.kb_manager.outputs.collections"
          },
          "data": {
            "description": "Generic result data",
            "title": "Data",
            "x-i18n-key": "nodes.rag.kb_manager.outputs.data"
          },
          "error": {
            "description": "Error message if any",
            "title": "Error",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.rag.kb_manager.outputs.error"
          },
          "message": {
            "description": "Operation message",
            "title": "Message",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.rag.kb_manager.outputs.message"
          },
          "operation": {
            "description": "Operation performed",
            "title": "Operation",
            "type": "string",
            "x-i18n-key": "nodes.rag.kb_manager.outputs.operation"
          },
          "success": {
            "description": "Whether operation succeeded",
            "title": "Success",
            "type": "boolean",
            "x-i18n-key": "nodes.rag.kb_manager.outputs.success"
          }
        },
        "required": [
          "operation",
          "success"
        ],
        "title": "KbManagerOutput",
        "type": "object",
        "x-collapsed-visible": [
          "operation",
          "data"
        ],
        "x-field-order": [
          "operation",
          "success",
          "collections",
          "collection_info",
          "message",
          "error",
          "data"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.rag.kb_manager"
    },
    {
      "typeId": "document/query",
      "name": "Query Document",
      "category": "document",
      "description": "Get document content, optionally return as block structure or Markdown format",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input for DocumentQueryNode",
        "properties": {
          "as_markdown": {
            "default": false,
            "description": "Optional: return content as markdown instead of blocks.",
            "title": "As Markdown",
            "type": "boolean",
            "x-i18n-key": "nodes.document.query.inputs.as_markdown"
          },
          "document_id": {
            "description": "ID of the document to query.",
            "title": "Document Id",
            "type": "string",
            "x-i18n-key": "nodes.document.query.inputs.document_id"
          },
          "include_content": {
            "default": true,
            "description": "Whether to include full block content (default: true).",
            "title": "Include Content",
            "type": "boolean",
            "x-i18n-key": "nodes.document.query.inputs.include_content"
          }
        },
        "required": [
          "document_id"
        ],
        "title": "DocumentQueryInput",
        "type": "object",
        "x-field-order": [
          "document_id",
          "include_content",
          "as_markdown"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "BlockInfo": {
            "description": "Block information in output",
            "properties": {
              "block_type": {
                "description": "Block type (paragraph, heading1, etc.).",
                "type": "string"
              },
              "children": {
                "description": "Child block IDs.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "content": {
                "description": "Text content of the block.",
                "type": "string"
              },
              "id": {
                "description": "Block ID.",
                "type": "string"
              }
            },
            "required": [
              "block_type",
              "children",
              "content",
              "id"
            ],
            "type": "object"
          }
        },
        "description": "Output from DocumentQueryNode",
        "properties": {
          "block_count": {
            "description": "Number of blocks.",
            "format": "uint",
            "minimum": 0,
            "title": "Block Count",
            "type": "integer",
            "x-i18n-key": "nodes.document.query.outputs.block_count"
          },
          "blocks": {
            "description": "All blocks in the document.",
            "items": {
              "$ref": "#/definitions/BlockInfo"
            },
            "type": "array",
            "x-i18n-key": "nodes.document.query.outputs.blocks"
          },
          "character_count": {
            "description": "Total character count.",
            "format": "uint",
            "minimum": 0,
            "type": "integer",
            "x-i18n-key": "nodes.document.query.outputs.character_count"
          },
          "content_type": {
            "description": "Content type (richtext/markdown).",
            "title": "Content Type",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.query.outputs.content_type"
          },
          "document_id": {
            "description": "Document ID (if found).",
            "title": "Document Id",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.query.outputs.document_id"
          },
          "error": {
            "description": "Error message if query failed.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.query.outputs.error"
          },
          "found": {
            "description": "Whether the document was found.",
            "type": "boolean",
            "x-i18n-key": "nodes.document.query.outputs.found"
          },
          "markdown": {
            "description": "Full document content as markdown (if as_markdown=true).",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.query.outputs.markdown"
          },
          "plain_text": {
            "description": "Plain text content.",
            "title": "Plain Text",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.query.outputs.plain_text"
          },
          "root_block_id": {
            "description": "Root block ID.",
            "title": "Root Block Id",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.query.outputs.root_block_id"
          },
          "success": {
            "description": "Whether the query was successful.",
            "type": "boolean",
            "x-i18n-key": "nodes.document.query.outputs.success"
          },
          "title": {
            "description": "Document title.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.query.outputs.title"
          }
        },
        "required": [
          "block_count",
          "blocks",
          "character_count",
          "found",
          "success"
        ],
        "title": "DocumentQueryOutput",
        "type": "object",
        "x-collapsed-visible": [
          "markdown",
          "plain_text"
        ],
        "x-field-order": [
          "success",
          "found",
          "document_id",
          "title",
          "blocks",
          "markdown",
          "plain_text",
          "block_count",
          "character_count",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.document.query"
    },
    {
      "typeId": "tools/schedule",
      "name": "Schedule Manager",
      "category": "scheduler",
      "description": "Directly list, create, update, pause, resume, cancel, and inspect scheduled tasks",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "action": {
            "default": "",
            "description": "Action type: list_tasks / get_task / create_task / update_task / pause_task / resume_task / cancel_task",
            "options": [
              {
                "label": "List Tasks",
                "value": "list_tasks"
              },
              {
                "label": "Get Task",
                "value": "get_task"
              },
              {
                "label": "Create Task",
                "value": "create_task"
              },
              {
                "label": "Update Task",
                "value": "update_task"
              },
              {
                "label": "Pause Task",
                "value": "pause_task"
              },
              {
                "label": "Resume Task",
                "value": "resume_task"
              },
              {
                "label": "Cancel Task",
                "value": "cancel_task"
              }
            ],
            "title": "Action",
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.tools.schedule.inputs.action"
          },
          "custom_cron": {
            "default": null,
            "description": "Custom cron expression",
            "title": "Custom Cron",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.custom_cron"
          },
          "frequency": {
            "default": null,
            "description": "Frequency: once, every_minute, hourly, daily, weekly, monthly, custom",
            "title": "Frequency",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.frequency"
          },
          "id": {
            "default": null,
            "description": "Numeric scheduled task ID",
            "title": "Task ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.id"
          },
          "label": {
            "default": null,
            "description": "Human-readable task label",
            "title": "Label",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.label"
          },
          "limit": {
            "default": 50,
            "description": "Max return count (default 50, max 500)",
            "format": "uint32",
            "minimum": 0,
            "title": "Limit",
            "type": "integer",
            "x-i18n-key": "nodes.tools.schedule.inputs.limit"
          },
          "max_retries": {
            "default": null,
            "description": "Maximum retries (default 3)",
            "format": "int32",
            "title": "Max Retries",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.max_retries"
          },
          "mode": {
            "default": "manual",
            "description": "Execution mode: Manual=user fills parameters, Llm=LLM auto-fills parameters",
            "enum": [
              "manual",
              "llm"
            ],
            "options": [
              {
                "label": "manual",
                "value": "manual"
              },
              {
                "label": "llm",
                "value": "llm"
              }
            ],
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.tools.schedule.inputs.mode"
          },
          "offset": {
            "default": 0,
            "description": "Pagination offset (default 0)",
            "format": "uint32",
            "minimum": 0,
            "title": "Offset",
            "type": "integer",
            "x-i18n-key": "nodes.tools.schedule.inputs.offset"
          },
          "params": {
            "default": null,
            "description": "Explicit workflow params object",
            "title": "Params",
            "x-i18n-key": "nodes.tools.schedule.inputs.params"
          },
          "priority": {
            "default": null,
            "description": "Execution priority (default 0)",
            "format": "int32",
            "title": "Priority",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.priority"
          },
          "run_at": {
            "default": null,
            "description": "Local datetime string, e.g. 2026-04-10T09:30 or 2026-04-10T09:30:00",
            "title": "Run At",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.run_at"
          },
          "status": {
            "default": null,
            "description": "Filter status for list_tasks: pending, running, completed, failed, cancelled, paused",
            "title": "Status",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.status"
          },
          "target_node_id": {
            "default": null,
            "description": "Node ID for raw_input routing",
            "title": "Target Node ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.target_node_id"
          },
          "task_text": {
            "default": null,
            "description": "Natural language task description",
            "title": "Task Text",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.task_text"
          },
          "timezone": {
            "default": null,
            "description": "IANA timezone, default Asia/Shanghai",
            "title": "Timezone",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.timezone"
          },
          "workflow_id": {
            "default": null,
            "description": "Workflow UUID",
            "title": "Workflow ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.inputs.workflow_id"
          }
        },
        "title": "ScheduleToolInput",
        "type": "object",
        "x-collapsed-visible": [
          "mode",
          "action"
        ],
        "x-field-order": [
          "mode",
          "action",
          "id",
          "workflow_id",
          "status",
          "limit",
          "offset",
          "run_at",
          "frequency",
          "custom_cron",
          "timezone",
          "task_text",
          "target_node_id",
          "params",
          "priority",
          "max_retries",
          "label"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "count": {
            "description": "Current page result count",
            "format": "uint",
            "minimum": 0,
            "title": "Count",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.outputs.count"
          },
          "data": {
            "description": "Query result or action result",
            "title": "Data",
            "x-i18n-key": "nodes.tools.schedule.outputs.data"
          },
          "error": {
            "description": "Error message",
            "title": "Error",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.outputs.error"
          },
          "status": {
            "description": "Operation status: ok / not_found / error / llm_config",
            "title": "Status",
            "type": "string",
            "x-i18n-key": "nodes.tools.schedule.outputs.status"
          },
          "total": {
            "description": "Total count before pagination",
            "format": "uint",
            "minimum": 0,
            "title": "Total",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.schedule.outputs.total"
          }
        },
        "required": [
          "status"
        ],
        "title": "ScheduleToolOutput",
        "type": "object",
        "x-collapsed-visible": [
          "status",
          "data"
        ],
        "x-field-order": [
          "status",
          "data",
          "count",
          "total",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.schedule"
    },
    {
      "typeId": "tools/mcp_hub",
      "name": "MCP Hub",
      "category": "tools",
      "description": "Connect one or more MCP servers in one place. Discover tools, manage visibility, and call tools with unified output.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "McpServerDefinition": {
            "properties": {
              "args_text": {
                "default": "",
                "description": "One argument per line.",
                "title": "Arguments",
                "type": "string",
                "x-control": "textarea"
              },
              "authorization": {
                "default": "",
                "description": "Authorization header value, for example: Bearer <token>.",
                "title": "Authorization",
                "type": "string"
              },
              "command": {
                "default": "",
                "description": "Command used for stdio transport, for example: uvx or npx.",
                "title": "Command",
                "type": "string"
              },
              "description": {
                "default": "",
                "description": "Optional note to help identify this server.",
                "title": "Description",
                "type": "string",
                "x-control": "textarea"
              },
              "editor_mode": {
                "default": "form",
                "description": "Choose how to edit this server: form fields or raw JSON.",
                "enum": [
                  "form",
                  "json"
                ],
                "options": [
                  {
                    "label": "Form",
                    "value": "form"
                  },
                  {
                    "label": "JSON",
                    "value": "json"
                  }
                ],
                "title": "Config Mode",
                "type": "string",
                "x-control": "select"
              },
              "enabled": {
                "default": true,
                "description": "Turn this MCP server on or off.",
                "title": "Enabled",
                "type": "boolean",
                "x-control": "switch"
              },
              "env_text": {
                "default": "",
                "description": "One env var per line in KEY=VALUE format.",
                "title": "Environment Variables",
                "type": "string",
                "x-control": "textarea"
              },
              "headers_text": {
                "default": "",
                "description": "One header per line in KEY=VALUE format.",
                "title": "Headers",
                "type": "string",
                "x-control": "textarea"
              },
              "long_running": {
                "default": false,
                "description": "Keep a persistent session for slower servers or longer workflows.",
                "title": "Long-Running Mode",
                "type": "boolean",
                "x-control": "switch"
              },
              "name": {
                "description": "Display name of this MCP server.",
                "title": "Name",
                "type": "string"
              },
              "raw_json": {
                "default": "",
                "description": "Full server config in JSON (used when Config Mode is JSON).",
                "title": "JSON Config",
                "type": "string",
                "x-control": "code-editor"
              },
              "timeout_secs": {
                "default": null,
                "description": "Per-server timeout in seconds. Leave empty to use the default.",
                "title": "Timeout (Seconds)",
                "type": [
                  "integer",
                  "null"
                ],
                "x-control": "number"
              },
              "transport": {
                "default": "stdio",
                "description": "How this MCP server is connected.",
                "enum": [
                  "stdio",
                  "streamable_http"
                ],
                "options": [
                  {
                    "label": "Stdio (stdin/stdout)",
                    "value": "stdio"
                  },
                  {
                    "label": "Streamable HTTP",
                    "value": "streamable_http"
                  }
                ],
                "title": "Transport",
                "type": "string",
                "x-control": "select"
              },
              "url": {
                "default": "",
                "description": "HTTP endpoint for this MCP server.",
                "title": "URL",
                "type": "string"
              }
            },
            "required": [
              "name"
            ],
            "type": "object"
          }
        },
        "properties": {
          "arguments": {
            "default": null,
            "description": "工具参数(JSON 对象,由用户或 LLM 提供)",
            "title": "Arguments",
            "type": [
              "object",
              "array",
              "string",
              "number",
              "integer",
              "boolean",
              "null"
            ],
            "x-advanced": true,
            "x-control": "code-editor",
            "x-debug-field": true,
            "x-i18n-key": "nodes.tools.mcp_hub.inputs.arguments"
          },
          "discover_only": {
            "default": false,
            "description": "发现模式开关:开启后只列出所有服务器的可用工具,不执行工具调用",
            "title": "Discover Only",
            "type": "boolean",
            "x-advanced": true,
            "x-control": "switch",
            "x-debug-field": true,
            "x-i18n-key": "nodes.tools.mcp_hub.inputs.discover_only"
          },
          "env_vars": {
            "additionalProperties": {
              "type": "string"
            },
            "default": null,
            "description": "Env vars from the credential node. These values are used for ${env:KEY} placeholders in URL, authorization, headers, arguments, and env fields.",
            "title": "Env Vars",
            "type": [
              "object",
              "null"
            ],
            "x-i18n-key": "nodes.tools.mcp_hub.inputs.env_vars"
          },
          "server_registry": {
            "default": [],
            "description": "结构化 MCP 服务器列表。前端可渲染为“列表 + 独立弹窗编辑器”。",
            "items": {
              "$ref": "#/definitions/McpServerDefinition"
            },
            "type": "array",
            "x-control": "mcp-server-manager",
            "x-fallback-control": "code-editor",
            "x-i18n-key": "nodes.tools.mcp_hub.inputs.server_registry",
            "x-mcp-server-manager": {
              "itemIdentityKey": "name",
              "statusField": "result",
              "supportsFormMode": true,
              "supportsModalEditor": true,
              "supportsRawJsonMode": true,
              "writeBack": {
                "format": "array",
                "targetField": "server_registry"
              }
            }
          },
          "timeout_ms": {
            "default": null,
            "description": "请求超时(毫秒,0 或留空表示不限时)",
            "title": "Timeout (ms)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.mcp_hub.inputs.timeout_ms"
          },
          "tool_name": {
            "default": "",
            "description": "要调用的工具名。格式 \"server_name:tool_name\"(多服务器时明确指定) 或直接 \"tool_name\"(单服务器时自动选择)。 discover_only 为 true 时忽略此字段。",
            "title": "Tool Name",
            "type": "string",
            "x-advanced": true,
            "x-debug-field": true,
            "x-i18n-key": "nodes.tools.mcp_hub.inputs.tool_name"
          },
          "tool_visibility": {
            "default": null,
            "description": "工具可见性配置(JSON 字符串,可选) 格式:{\"server:tool\": {\"visible\": true, \"callable\": true}, \"*\": {...}}",
            "title": "Tool Visibility",
            "type": "string",
            "x-advanced": true,
            "x-control": "textarea",
            "x-deprecated": true,
            "x-i18n-key": "nodes.tools.mcp_hub.inputs.tool_visibility"
          },
          "visibility_config": {
            "additionalProperties": true,
            "default": null,
            "description": "结构化工具可见性配置(推荐)\n\n格式: { \"servers\": {\"server-a\": {\"visible\": true, \"callable\": true}, \"*\": {...}}, \"tools\": {\"server-a:search\": {\"visible\": true, \"callable\": true}, \"*\": {...}} }",
            "properties": {
              "cache_config_key": true,
              "cache_tested_at": true,
              "cached_discovered_tools": true,
              "cached_upstream_servers": true,
              "servers": true,
              "tools": true
            },
            "title": "Visibility Config",
            "type": "object",
            "x-control": "mcp-visibility-editor",
            "x-fallback-control": "code-editor",
            "x-i18n-key": "nodes.tools.mcp_hub.inputs.visibility_config",
            "x-mcp-visibility-editor": {
              "dataSource": {
                "discoveredToolsField": "discovered_tools",
                "upstreamServersField": "upstream_servers"
              },
              "supportsBatchActions": true,
              "writeBack": {
                "format": "structured",
                "targetField": "visibility_config"
              }
            }
          }
        },
        "title": "McpHubInput",
        "type": "object",
        "x-collapsed-visible": [
          "server_registry"
        ],
        "x-field-order": [
          "server_registry",
          "tool_name",
          "arguments",
          "tool_visibility",
          "visibility_config",
          "discover_only",
          "timeout_ms",
          "env_vars"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "result": {
            "description": "Unified result with summary, server status, discovered tools, and optional tool call output.",
            "title": "Result",
            "x-i18n-key": "nodes.tools.mcp_hub.outputs.result"
          }
        },
        "required": [
          "result"
        ],
        "title": "McpHubOutput",
        "type": "object",
        "x-collapsed-visible": [
          "result"
        ],
        "x-field-order": [
          "result"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.mcp_hub"
    },
    {
      "typeId": "tools/http",
      "name": "HTTP Tool",
      "category": "tools",
      "description": "Send HTTP requests to specified URL, supports manual mode and LLM mode",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "body": {
            "default": null,
            "description": "Request body (JSON string or form data)",
            "maxLength": 200000,
            "title": "Body",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.tools.http.inputs.body"
          },
          "credential_id": {
            "default": null,
            "description": "HTTP authentication credential ID (optional, for Bearer Token or Basic Auth)",
            "title": "Credential",
            "type": "string",
            "x-control": "credential-select",
            "x-credential-providers": [
              "bearer",
              "basic"
            ],
            "x-i18n-key": "nodes.tools.http.inputs.credential_id"
          },
          "headers": {
            "additionalProperties": {
              "type": "string"
            },
            "default": null,
            "description": "Custom request headers (optional)",
            "title": "Headers",
            "type": [
              "object",
              "null"
            ],
            "x-i18n-key": "nodes.tools.http.inputs.headers"
          },
          "method": {
            "default": "GET",
            "description": "HTTP method",
            "enum": [
              "GET",
              "POST",
              "PUT",
              "DELETE",
              "PATCH"
            ],
            "options": [
              {
                "label": "GET",
                "value": "GET"
              },
              {
                "label": "POST",
                "value": "POST"
              },
              {
                "label": "PUT",
                "value": "PUT"
              },
              {
                "label": "DELETE",
                "value": "DELETE"
              },
              {
                "label": "PATCH",
                "value": "PATCH"
              }
            ],
            "title": "Method",
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.tools.http.inputs.method"
          },
          "mode": {
            "default": "manual",
            "description": "Execution mode: Manual=user fills all parameters, Llm=LLM auto-fills parameters",
            "oneOf": [
              {
                "description": "手动模式:用户在前端填写所有参数",
                "enum": [
                  "manual"
                ],
                "type": "string"
              },
              {
                "description": "LLM 模式:LLM 通过 ReAct 调用时填充参数",
                "enum": [
                  "llm"
                ],
                "type": "string"
              }
            ],
            "title": "Execution Mode",
            "x-control": "select",
            "x-i18n-key": "nodes.tools.http.inputs.mode"
          },
          "timeout_seconds": {
            "default": 30,
            "description": "Timeout in seconds",
            "format": "uint64",
            "maximum": 300,
            "minimum": 1,
            "title": "Timeout (seconds)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.http.inputs.timeout_seconds"
          },
          "url": {
            "default": null,
            "description": "Target URL (filled by LLM in LLM mode, or by user in manual mode)",
            "maxLength": 2048,
            "title": "URL",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.http.inputs.url"
          }
        },
        "title": "HttpInput",
        "type": "object",
        "x-collapsed-visible": [
          "credential_id",
          "mode",
          "url"
        ],
        "x-field-order": [
          "credential_id",
          "mode",
          "url",
          "method",
          "headers",
          "body",
          "timeout_seconds"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "HTTP 工具执行输出",
        "properties": {
          "body": {
            "description": "Response body content",
            "title": "Body",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.http.outputs.body"
          },
          "body_truncated": {
            "description": "Whether response body was truncated",
            "title": "Body Truncated",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.http.outputs.body_truncated"
          },
          "credential_used": {
            "description": "Whether credential authentication was used",
            "title": "Credential Used",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.http.outputs.credential_used"
          },
          "elapsed_ms": {
            "description": "Request elapsed time in milliseconds",
            "format": "uint64",
            "minimum": 0,
            "title": "Elapsed Ms",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.http.outputs.elapsed_ms"
          },
          "headers": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Response headers",
            "title": "Headers",
            "type": [
              "object",
              "null"
            ],
            "x-i18n-key": "nodes.tools.http.outputs.headers"
          },
          "mode": {
            "description": "Execution mode",
            "title": "Mode",
            "type": "string",
            "x-i18n-key": "nodes.tools.http.outputs.mode"
          },
          "status_code": {
            "description": "HTTP response status code",
            "format": "uint16",
            "minimum": 0,
            "title": "Status Code",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.http.outputs.status_code"
          },
          "timeout_seconds": {
            "description": "Timeout in seconds",
            "format": "uint64",
            "minimum": 0,
            "title": "Timeout Seconds",
            "type": "integer",
            "x-i18n-key": "nodes.tools.http.outputs.timeout_seconds"
          }
        },
        "required": [
          "body_truncated",
          "credential_used",
          "mode",
          "timeout_seconds"
        ],
        "title": "HttpOutput",
        "type": "object",
        "x-collapsed-visible": [
          "credential_id",
          "mode",
          "url"
        ],
        "x-field-order": [
          "mode",
          "timeout_seconds",
          "status_code",
          "body",
          "body_truncated",
          "headers",
          "elapsed_ms",
          "credential_used"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.http"
    },
    {
      "typeId": "tools/workflow_inspect",
      "name": "Workflow Inspector",
      "category": "tools",
      "description": "Read-only query for workflow definitions, node schemas, and execution status. list_workflows=list workflows (name/tag filter, pagination), get_workflow=get workflow details (nodes/edges/tags), list_node_types=list all node types, get_node_schema=get node input/output schema, get_execution=query execution status and node outputs by execution_id, list_executions=list execution history for a workflow (requires workflow_id)",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "action": {
            "default": "",
            "description": "Operation type: list_workflows / get_workflow / list_node_types / get_node_schema",
            "options": [
              {
                "label": "List Workflows",
                "value": "list_workflows"
              },
              {
                "label": "Get Workflow",
                "value": "get_workflow"
              },
              {
                "label": "List Node Types",
                "value": "list_node_types"
              },
              {
                "label": "Get Node Schema",
                "value": "get_node_schema"
              },
              {
                "label": "Get Execution",
                "value": "get_execution"
              },
              {
                "label": "List Executions",
                "value": "list_executions"
              }
            ],
            "title": "Action",
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.tools.workflow_inspect.inputs.action"
          },
          "category_filter": {
            "default": null,
            "description": "Node category filter (optional for list_node_types)",
            "title": "Category Filter",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.workflow_inspect.inputs.category_filter"
          },
          "execution_id": {
            "default": null,
            "description": "Execution UUID (required for get_execution)",
            "title": "Execution ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.workflow_inspect.inputs.execution_id"
          },
          "limit": {
            "default": 50,
            "description": "Max return count (default 50, max 200)",
            "format": "uint32",
            "minimum": 0,
            "title": "Limit",
            "type": "integer",
            "x-i18n-key": "nodes.tools.workflow_inspect.inputs.limit"
          },
          "mode": {
            "default": "manual",
            "description": "Execution mode: Manual=user fills parameters, Llm=LLM auto-fills parameters",
            "enum": [
              "manual",
              "llm"
            ],
            "options": [
              {
                "label": "manual",
                "value": "manual"
              },
              {
                "label": "llm",
                "value": "llm"
              }
            ],
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.tools.workflow_inspect.inputs.mode"
          },
          "name_filter": {
            "default": null,
            "description": "Workflow name filter (optional for list_workflows, fuzzy match)",
            "title": "Name Filter",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.workflow_inspect.inputs.name_filter"
          },
          "node_type": {
            "default": null,
            "description": "Node type ID (required for get_node_schema, e.g. agent/llm)",
            "title": "Node Type",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.workflow_inspect.inputs.node_type"
          },
          "offset": {
            "default": 0,
            "description": "Pagination offset (default 0)",
            "format": "uint32",
            "minimum": 0,
            "title": "Offset",
            "type": "integer",
            "x-i18n-key": "nodes.tools.workflow_inspect.inputs.offset"
          },
          "tag_filter": {
            "default": null,
            "description": "Workflow tag filter (optional for list_workflows, exact match)",
            "title": "Tag Filter",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.workflow_inspect.inputs.tag_filter"
          },
          "workflow_id": {
            "default": null,
            "description": "Workflow UUID (required for get_workflow)",
            "title": "Workflow ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.workflow_inspect.inputs.workflow_id"
          }
        },
        "title": "WorkflowInspectInput",
        "type": "object",
        "x-collapsed-visible": [
          "mode"
        ],
        "x-field-order": [
          "mode",
          "action",
          "workflow_id",
          "name_filter",
          "tag_filter",
          "limit",
          "offset",
          "node_type",
          "category_filter",
          "execution_id"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "count": {
            "description": "Current page result count",
            "format": "uint",
            "minimum": 0,
            "title": "Count",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.workflow_inspect.outputs.count"
          },
          "data": {
            "description": "Query result (JSON format)",
            "title": "Data",
            "x-i18n-key": "nodes.tools.workflow_inspect.outputs.data"
          },
          "error": {
            "description": "Error message",
            "title": "Error",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.workflow_inspect.outputs.error"
          },
          "status": {
            "description": "Operation status: ok / not_found / error",
            "title": "Status",
            "type": "string",
            "x-i18n-key": "nodes.tools.workflow_inspect.outputs.status"
          },
          "total": {
            "description": "Total count (after filtering, before pagination)",
            "format": "uint",
            "minimum": 0,
            "title": "Total",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.workflow_inspect.outputs.total"
          }
        },
        "required": [
          "status"
        ],
        "title": "WorkflowInspectOutput",
        "type": "object",
        "x-collapsed-visible": [
          "status",
          "data"
        ],
        "x-field-order": [
          "status",
          "data",
          "count",
          "total",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.workflow_inspect"
    },
    {
      "typeId": "rag/document_indexer",
      "name": "Document Indexer",
      "category": "rag",
      "description": "Index documents into vector database (standard/enhanced modes)",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Document Indexer input",
        "properties": {
          "child_chunks": {
            "default": null,
            "description": "Child chunks from chunker node (optional)",
            "items": true,
            "title": "Child Chunks",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.rag.document_indexer.inputs.child_chunks"
          },
          "content": {
            "default": null,
            "description": "Document text content to index (optional if chunks are provided from chunker)",
            "title": "Document Content",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.rag.document_indexer.inputs.content"
          },
          "document_id": {
            "default": null,
            "description": "Document identifier (optional, auto-generated if not provided)",
            "title": "Document ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.rag.document_indexer.inputs.document_id"
          },
          "document_title": {
            "default": null,
            "description": "Readable document title/source label (optional, falls back to workspace name)",
            "title": "Document Title",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.rag.document_indexer.inputs.document_title"
          },
          "embedding_config": {
            "additionalProperties": true,
            "description": "Embedding configuration object from config node",
            "title": "Embedding Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.rag.document_indexer.inputs.embedding_config",
            "x-port": true
          },
          "generate_context": {
            "default": null,
            "description": "Use LLM to generate context descriptions for each chunk (enhanced mode)",
            "title": "Generate Context",
            "type": [
              "boolean",
              "null"
            ],
            "x-i18n-key": "nodes.rag.document_indexer.inputs.generate_context"
          },
          "index_mode": {
            "default": null,
            "description": "Standard or enhanced mode",
            "title": "Index Mode",
            "type": "string",
            "x-control": "select",
            "x-default": "standard",
            "x-i18n-key": "nodes.rag.document_indexer.inputs.index_mode",
            "x-options": [
              {
                "description": "Child vectors only (economy)",
                "label": "Standard",
                "value": "standard"
              },
              {
                "description": "Parent + child + context vectors (full-featured)",
                "label": "Enhanced",
                "value": "enhanced"
              }
            ]
          },
          "kb_id": {
            "description": "Target knowledge base (collection resolved from DB, workspace-validated)",
            "title": "Knowledge Base",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces/{workspace_id}/knowledge-bases?limit=200",
            "x-control": "dynamic-select",
            "x-depends-on": "workspace_id",
            "x-i18n-key": "nodes.rag.document_indexer.inputs.kb_id"
          },
          "llm_config": {
            "additionalProperties": true,
            "default": null,
            "description": "LLM configuration object from config node (optional, for context generation)",
            "title": "LLM Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.rag.document_indexer.inputs.llm_config",
            "x-port": true
          },
          "parent_chunks": {
            "default": null,
            "description": "Parent chunks from chunker node (optional, if provided skips internal chunking)",
            "items": true,
            "title": "Parent Chunks",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.rag.document_indexer.inputs.parent_chunks"
          },
          "qdrant_config": {
            "additionalProperties": true,
            "description": "Qdrant configuration object from config node",
            "title": "Qdrant Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.rag.document_indexer.inputs.qdrant_config",
            "x-port": true
          },
          "version": {
            "default": null,
            "description": "Document version number (optional, for idempotency check)",
            "format": "uint32",
            "minimum": 0,
            "title": "Document Version",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.rag.document_indexer.inputs.version"
          },
          "workspace_id": {
            "description": "Target workspace (required for permission validation)",
            "title": "Workspace ID",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces?limit=200",
            "x-cache-key": "static_select:/api/v1/workspaces?limit=200",
            "x-control": "dynamic-select",
            "x-i18n-key": "nodes.rag.document_indexer.inputs.workspace_id"
          }
        },
        "required": [
          "embedding_config",
          "kb_id",
          "qdrant_config",
          "workspace_id"
        ],
        "title": "DocumentIndexerInput",
        "type": "object",
        "x-collapsed-visible": [
          "qdrant_config",
          "parent_chunks",
          "child_chunks",
          "embedding_config",
          "llm_config"
        ],
        "x-field-order": [
          "workspace_id",
          "kb_id",
          "qdrant_config",
          "content",
          "document_id",
          "document_title",
          "version",
          "parent_chunks",
          "child_chunks",
          "index_mode",
          "embedding_config",
          "generate_context",
          "llm_config"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Document Indexer output",
        "properties": {
          "child_chunks": {
            "description": "Number of child chunks created",
            "format": "uint",
            "minimum": 0,
            "title": "Child Chunks",
            "type": "integer",
            "x-i18n-key": "nodes.rag.document_indexer.outputs.child_chunks"
          },
          "collection_name": {
            "description": "Target collection name",
            "title": "Collection Name",
            "type": "string",
            "x-i18n-key": "nodes.rag.document_indexer.outputs.collection_name"
          },
          "context_generated": {
            "description": "Whether context descriptions were generated",
            "title": "Context Generated",
            "type": "boolean",
            "x-i18n-key": "nodes.rag.document_indexer.outputs.context_generated"
          },
          "document_id": {
            "description": "Indexed document ID",
            "title": "Document ID",
            "type": "string",
            "x-i18n-key": "nodes.rag.document_indexer.outputs.document_id"
          },
          "error": {
            "description": "Error message if any",
            "title": "Error",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.rag.document_indexer.outputs.error"
          },
          "index_mode": {
            "description": "Index mode used",
            "title": "Index Mode",
            "type": "string",
            "x-i18n-key": "nodes.rag.document_indexer.outputs.index_mode"
          },
          "parent_chunks": {
            "description": "Number of parent chunks created",
            "format": "uint",
            "minimum": 0,
            "title": "Parent Chunks",
            "type": "integer",
            "x-i18n-key": "nodes.rag.document_indexer.outputs.parent_chunks"
          },
          "skipped": {
            "default": false,
            "description": "Whether skipped due to idempotency check",
            "title": "Skipped",
            "type": "boolean",
            "x-i18n-key": "nodes.rag.document_indexer.outputs.skipped"
          },
          "success": {
            "description": "Whether indexing succeeded",
            "title": "Success",
            "type": "boolean",
            "x-i18n-key": "nodes.rag.document_indexer.outputs.success"
          },
          "summary": {
            "description": "Execution result summary",
            "title": "Summary",
            "type": "string",
            "x-i18n-key": "nodes.rag.document_indexer.outputs.summary"
          },
          "vectors_stored": {
            "description": "Total vectors stored",
            "format": "uint",
            "minimum": 0,
            "title": "Vectors Stored",
            "type": "integer",
            "x-i18n-key": "nodes.rag.document_indexer.outputs.vectors_stored"
          }
        },
        "required": [
          "child_chunks",
          "collection_name",
          "context_generated",
          "document_id",
          "index_mode",
          "parent_chunks",
          "success",
          "summary",
          "vectors_stored"
        ],
        "title": "DocumentIndexerOutput",
        "type": "object",
        "x-collapsed-visible": [
          "context_generated"
        ],
        "x-field-order": [
          "document_id",
          "parent_chunks",
          "child_chunks",
          "vectors_stored",
          "context_generated",
          "index_mode",
          "collection_name",
          "skipped",
          "success",
          "summary",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.rag.document_indexer"
    },
    {
      "typeId": "workspace/settings",
      "name": "Workspace Settings",
      "category": "workspace",
      "description": "Read or update workspace settings (theme, language, features, quotas)",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "ai_chat_enabled": {
            "default": null,
            "description": "Enable AI chat features (update mode)",
            "title": "AI Chat Enabled",
            "type": [
              "boolean",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.settings.inputs.ai_chat_enabled"
          },
          "default_workflow_id": {
            "default": null,
            "description": "Default conversation workflow ID (update mode)",
            "title": "Default Workflow ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.settings.inputs.default_workflow_id"
          },
          "knowledge_base_enabled": {
            "default": null,
            "description": "Enable knowledge base features (update mode)",
            "title": "Knowledge Base Enabled",
            "type": [
              "boolean",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.settings.inputs.knowledge_base_enabled"
          },
          "language": {
            "default": null,
            "description": "Default language code, e.g. zh-CN, en-US (update mode)",
            "title": "Language",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.settings.inputs.language"
          },
          "mode": {
            "default": "get",
            "description": "get: Read settings; update: Update settings",
            "enum": [
              "get",
              "update"
            ],
            "options": [
              {
                "label": "get",
                "value": "get"
              },
              {
                "label": "update",
                "value": "update"
              }
            ],
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.workspace.settings.inputs.mode"
          },
          "theme": {
            "default": null,
            "description": "Theme name (update mode)",
            "title": "Theme",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.settings.inputs.theme"
          },
          "workspace_id": {
            "description": "Target workspace",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces?limit=200",
            "x-cache-key": "static_select:/api/v1/workspaces?limit=200",
            "x-control": "dynamic-select",
            "x-i18n-key": "nodes.workspace.settings.inputs.workspace_id"
          }
        },
        "required": [
          "workspace_id"
        ],
        "title": "WorkspaceSettingsNodeInput",
        "type": "object",
        "x-field-order": [
          "mode",
          "workspace_id",
          "theme",
          "language",
          "default_workflow_id",
          "ai_chat_enabled",
          "knowledge_base_enabled"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "default_workflow_id": {
            "title": "Default Workflow Id",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.settings.outputs.default_workflow_id"
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.settings.outputs.error"
          },
          "language": {
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.settings.outputs.language"
          },
          "settings_json": {
            "title": "Settings Json",
            "type": "string",
            "x-i18n-key": "nodes.workspace.settings.outputs.settings_json"
          },
          "success": {
            "type": "boolean",
            "x-i18n-key": "nodes.workspace.settings.outputs.success"
          },
          "theme": {
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.settings.outputs.theme"
          },
          "workspace_id": {
            "title": "Workspace Id",
            "type": "string",
            "x-i18n-key": "nodes.workspace.settings.outputs.workspace_id"
          }
        },
        "required": [
          "settings_json",
          "success",
          "workspace_id"
        ],
        "title": "WorkspaceSettingsNodeOutput",
        "type": "object",
        "x-collapsed-visible": [
          "success",
          "theme",
          "language",
          "error"
        ],
        "x-field-order": [
          "success",
          "workspace_id",
          "default_workflow_id",
          "theme",
          "language",
          "settings_json",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.workspace.settings"
    },
    {
      "typeId": "tools/list_directory",
      "name": "List Directory",
      "category": "tools",
      "description": "List directory contents, return structured entry list. Supports glob filtering and recursive depth control, max 200 entries.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "directory_path": {
            "description": "Absolute directory path to list",
            "title": "Directory Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.list_directory.inputs.directory_path"
          },
          "max_depth": {
            "description": "Recursion depth (0=directory itself only, 1=direct children). Default 1, max 5.",
            "format": "uint32",
            "minimum": 0,
            "title": "Max Depth",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.list_directory.inputs.max_depth"
          },
          "pattern": {
            "description": "Filename glob filter (e.g. \"*.rs\"), matches filename only, not full path",
            "title": "Pattern",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.list_directory.inputs.pattern"
          },
          "show_hidden": {
            "default": false,
            "description": "Whether to show hidden files/directories (starting with .), default false",
            "title": "Show Hidden",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.list_directory.inputs.show_hidden"
          }
        },
        "required": [
          "directory_path"
        ],
        "title": "ListDirectoryInput",
        "type": "object"
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "DirEntry": {
            "description": "目录条目",
            "properties": {
              "absolute_path": {
                "description": "绝对规范路径",
                "type": "string"
              },
              "entry_type": {
                "allOf": [
                  {
                    "$ref": "#/definitions/EntryType"
                  }
                ],
                "description": "条目类型"
              },
              "is_binary": {
                "description": "是否为二进制文件(仅 File 有效,目录/链接为 None)",
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "modified": {
                "description": "修改时间(ISO 8601)",
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "description": "文件/目录名",
                "type": "string"
              },
              "relative_path": {
                "description": "相对于 directory_path 的路径",
                "type": "string"
              },
              "size_bytes": {
                "description": "文件大小(目录为 None)",
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "required": [
              "absolute_path",
              "entry_type",
              "name",
              "relative_path"
            ],
            "type": "object"
          },
          "EntryType": {
            "description": "条目类型",
            "enum": [
              "file",
              "dir",
              "symlink"
            ],
            "type": "string"
          }
        },
        "properties": {
          "directory_path": {
            "description": "规范化后的目录路径",
            "title": "Directory Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.list_directory.outputs.directory_path"
          },
          "elapsed_ms": {
            "description": "操作耗时(毫秒)",
            "format": "uint64",
            "minimum": 0,
            "title": "Elapsed Ms",
            "type": "integer",
            "x-i18n-key": "nodes.tools.list_directory.outputs.elapsed_ms"
          },
          "entries": {
            "description": "条目列表(按 name 字母序排列)",
            "items": {
              "$ref": "#/definitions/DirEntry"
            },
            "type": "array",
            "x-i18n-key": "nodes.tools.list_directory.outputs.entries"
          },
          "error": {
            "description": "错误信息",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.list_directory.outputs.error"
          },
          "total_entries": {
            "description": "实际返回条目数",
            "format": "uint32",
            "minimum": 0,
            "title": "Total Entries",
            "type": "integer",
            "x-i18n-key": "nodes.tools.list_directory.outputs.total_entries"
          },
          "truncated": {
            "description": "是否因超过 200 条而截断",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.list_directory.outputs.truncated"
          }
        },
        "required": [
          "directory_path",
          "elapsed_ms",
          "entries",
          "total_entries",
          "truncated"
        ],
        "title": "ListDirectoryOutput",
        "type": "object",
        "x-collapsed-visible": [
          "directory_path",
          "entries"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.list_directory"
    },
    {
      "typeId": "tools/code_js",
      "name": "JavaScript Executor",
      "category": "tools",
      "description": "Run JavaScript in QuickJS engine sandbox (NO syscalls, NO network, NO filesystem — fully isolated). FAIL-CLOSED: errors if QuickJS is unavailable. Use for: pure computation, JSON/object transformation, string manipulation, math. Do NOT use for network requests (→ Shell) or complex algorithms needing libraries (→ Python). Just provide script and input. Example: {\"script\":\"input.values.reduce((a,b)=>a+b,0)\",\"input\":{\"values\":[1,2,3]}}",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "input": {
            "default": null,
            "description": "Input data (any JSON), accessible via `input` variable in script",
            "title": "Input",
            "x-i18n-key": "nodes.tools.code_js.inputs.input"
          },
          "memory_mb": {
            "default": 128,
            "description": "Memory limit in MB. QuickJS engine internal soft constraint. Default 128MB.",
            "format": "uint64",
            "maximum": 1024,
            "minimum": 16,
            "title": "Memory Limit (MB)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.code_js.inputs.memory_mb"
          },
          "script": {
            "default": null,
            "description": "[Required] JavaScript script, last expression value becomes result. Example: input.values.reduce((a,b)=>a+b,0)",
            "title": "Script",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.tools.code_js.inputs.script",
            "x-rows": 5
          },
          "timeout_ms": {
            "default": 5000,
            "description": "Timeout in milliseconds. Default 5000ms, max 300000ms.",
            "format": "uint64",
            "maximum": 300000,
            "minimum": 100,
            "title": "Timeout (ms)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.code_js.inputs.timeout_ms"
          }
        },
        "title": "CodeJsInput",
        "type": "object",
        "x-collapsed-visible": [
          "script"
        ],
        "x-field-order": [
          "input",
          "script",
          "timeout_ms",
          "memory_mb"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "ExecutionMetrics": {
            "properties": {
              "duration_ms": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "input_size_bytes": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "output_size_bytes": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "peak_memory_bytes": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "runtime_type": {
                "type": "string"
              },
              "script_hash": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "duration_ms",
              "input_size_bytes",
              "output_size_bytes",
              "peak_memory_bytes",
              "runtime_type"
            ],
            "type": "object"
          }
        },
        "properties": {
          "isolation_level": {
            "description": "Actual isolation level used: bubblewrap > quickjs > python",
            "title": "Isolation Level",
            "type": "string",
            "x-i18n-key": "nodes.tools.code_js.outputs.isolation_level"
          },
          "metrics": {
            "allOf": [
              {
                "$ref": "#/definitions/ExecutionMetrics"
              }
            ],
            "description": "Execution performance metrics",
            "title": "Metrics",
            "x-i18n-key": "nodes.tools.code_js.outputs.metrics"
          },
          "result": {
            "description": "Script execution result",
            "title": "Result",
            "x-i18n-key": "nodes.tools.code_js.outputs.result"
          },
          "stderr": {
            "description": "Standard error",
            "title": "Stderr",
            "type": "string",
            "x-i18n-key": "nodes.tools.code_js.outputs.stderr"
          },
          "stdout": {
            "description": "Standard output",
            "title": "Stdout",
            "type": "string",
            "x-i18n-key": "nodes.tools.code_js.outputs.stdout"
          },
          "warnings": {
            "description": "Script validation warnings",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array",
            "x-i18n-key": "nodes.tools.code_js.outputs.warnings"
          }
        },
        "required": [
          "isolation_level",
          "metrics",
          "result",
          "stderr",
          "stdout",
          "warnings"
        ],
        "title": "CodeOutput",
        "type": "object",
        "x-collapsed-visible": [
          "result"
        ],
        "x-field-order": [
          "result",
          "isolation_level",
          "metrics",
          "stdout",
          "stderr",
          "warnings"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.code_js"
    },
    {
      "typeId": "ai/llm_branch",
      "name": "LLM Field Branch",
      "category": "agent",
      "description": "Route by field conditions: supports operator comparison, dot nested path, Schema hint generation, enhanced fallback metadata",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "输入结构",
        "properties": {
          "branch_fields": {
            "default": [],
            "description": "Branch field list (click + to add; each entry auto-generates a corresponding output port)",
            "items": {
              "properties": {
                "description": {
                  "description": "Field description (used for Schema hint generation)",
                  "type": "string"
                },
                "field_name": {
                  "description": "Field path (supports dot notation for nested fields, e.g. action.name)",
                  "type": "string"
                },
                "match_value": {
                  "description": "Match value (required for Equals/NotEquals/Contains/GreaterThan/LessThan)",
                  "type": "string"
                },
                "operator": {
                  "default": "truthy",
                  "description": "Match operator (default: Truthy)",
                  "enum": [
                    "truthy",
                    "exists",
                    "equals",
                    "not_equals",
                    "contains",
                    "greater_than",
                    "less_than"
                  ],
                  "type": "string",
                  "x-control": "select"
                }
              },
              "type": "object"
            },
            "title": "Branch Fields",
            "type": "array",
            "x-dynamic-array": {
              "allowAdd": true,
              "allowRemove": true,
              "maxPorts": 20,
              "minPorts": 0,
              "portPrefix": "branch"
            },
            "x-i18n-key": "nodes.ai.llm_branch.inputs.branch_fields"
          },
          "context": {
            "additionalProperties": true,
            "default": null,
            "description": "Input AgentContext (optional)",
            "title": "Agent Context",
            "type": "object",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.ai.llm_branch.inputs.context",
            "x-language": "json",
            "x-port": true,
            "x-rows": 2
          },
          "custom_data": {
            "default": null,
            "description": "Custom JSON data",
            "title": "Custom Data",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.ai.llm_branch.inputs.custom_data",
            "x-language": "json",
            "x-rows": 2
          },
          "generate_schema": {
            "default": false,
            "description": "Enable auto-generated JSON Schema hint output to schema_hint port (can connect to upstream LLM's system_prompt)",
            "title": "Generate Schema",
            "type": "boolean",
            "x-i18n-key": "nodes.ai.llm_branch.inputs.generate_schema"
          },
          "payload_source": {
            "default": "response",
            "description": "Select data extraction source",
            "oneOf": [
              {
                "description": "从 response 字段解析 JSON",
                "enum": [
                  "response"
                ],
                "type": "string"
              },
              {
                "description": "从完整 context 序列化为 JSON",
                "enum": [
                  "context"
                ],
                "type": "string"
              },
              {
                "description": "从 custom_data 字段取值",
                "enum": [
                  "custom"
                ],
                "type": "string"
              }
            ],
            "title": "Payload Source",
            "x-control": "select",
            "x-i18n-key": "nodes.ai.llm_branch.inputs.payload_source"
          },
          "response": {
            "default": "",
            "description": "LLM response text (JSON format)",
            "maxLength": 200000,
            "title": "Response",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.ai.llm_branch.inputs.response",
            "x-language": "json",
            "x-rows": 2
          },
          "strict_mode": {
            "default": false,
            "description": "Error on JSON parse failure (false routes error reason to context_out fallback)",
            "title": "Strict Mode",
            "type": "boolean",
            "x-i18n-key": "nodes.ai.llm_branch.inputs.strict_mode"
          }
        },
        "title": "LlmBranchInput",
        "type": "object",
        "x-collapsed-visible": [
          "response",
          "branch_fields"
        ],
        "x-field-order": [
          "context",
          "response",
          "custom_data",
          "payload_source",
          "branch_fields",
          "strict_mode",
          "generate_schema"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "输出结构",
        "properties": {
          "branch_outputs": {
            "description": "Branch output list, corresponding 1:1 with branch_fields (AgentContext on match, null on miss)",
            "title": "Branch Outputs",
            "type": "array",
            "x-i18n-key": "nodes.ai.llm_branch.outputs.branch_outputs",
            "x-port": true
          },
          "context_out": {
            "additionalProperties": true,
            "description": "Fallback output: outputs AgentContext from this port when no branch fields match (includes routing diagnostic metadata)",
            "title": "Context Out",
            "type": "object",
            "x-i18n-key": "nodes.ai.llm_branch.outputs.context_out",
            "x-port": true
          },
          "schema_hint": {
            "additionalProperties": true,
            "description": "Auto-generated structured output hint (can connect to upstream LLM node's system_prompt port)",
            "title": "JSON Schema",
            "type": "object",
            "x-i18n-key": "nodes.ai.llm_branch.outputs.schema_hint",
            "x-port": true
          }
        },
        "required": [
          "branch_outputs",
          "context_out",
          "schema_hint"
        ],
        "title": "LlmBranchOutput",
        "type": "object",
        "x-collapsed-visible": [
          "context_out",
          "branch_outputs"
        ],
        "x-field-order": [
          "branch_outputs",
          "context_out",
          "schema_hint"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.ai.llm_branch"
    },
    {
      "typeId": "ai/qdrant_config",
      "name": "Qdrant Config",
      "category": "agent",
      "description": "Configure a Qdrant vector database connection (local/cloud/self-hosted)",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Qdrant 配置节点输入",
        "properties": {
          "collection_name": {
            "default": null,
            "description": "Name of the Qdrant collection (optional, auto-derived from knowledge base if not set)",
            "title": "Collection Name",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.ai.qdrant_config.inputs.collection_name"
          },
          "credential_id": {
            "default": null,
            "description": "Credential for Qdrant Cloud or an authenticated self-hosted server",
            "title": "Credential",
            "type": "string",
            "x-conditional": {
              "field": "mode",
              "values": [
                "cloud",
                "self_hosted"
              ]
            },
            "x-control": "credential-select",
            "x-credential-providers": [
              "qdrant"
            ],
            "x-i18n-key": "nodes.ai.qdrant_config.inputs.credential_id",
            "x-optional-for": [
              "local"
            ]
          },
          "enable_fulltext": {
            "default": null,
            "description": "Whether to enable a BM25 full-text search index on the collection",
            "title": "Enable Full-Text Search",
            "type": [
              "boolean",
              "null"
            ],
            "x-i18n-key": "nodes.ai.qdrant_config.inputs.enable_fulltext"
          },
          "mode": {
            "default": "local",
            "description": "Select how Qdrant is deployed",
            "title": "Deployment Mode",
            "type": "string",
            "x-control": "select",
            "x-default": "local",
            "x-i18n-key": "nodes.ai.qdrant_config.inputs.mode",
            "x-options": [
              {
                "description": "Connect to a Qdrant instance running in local Docker (localhost:6334)",
                "label": "Local Docker",
                "value": "local"
              },
              {
                "description": "Connect to the hosted Qdrant Cloud service",
                "label": "Qdrant Cloud",
                "value": "cloud"
              },
              {
                "description": "Connect to a self-hosted Qdrant server",
                "label": "Self-hosted Server",
                "value": "self_hosted"
              }
            ]
          },
          "url": {
            "default": null,
            "description": "Qdrant gRPC endpoint URL (default for local mode: http://localhost:6334)",
            "title": "Connection URL",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.ai.qdrant_config.inputs.url"
          }
        },
        "title": "QdrantConfigInput",
        "type": "object",
        "x-field-order": [
          "mode",
          "url",
          "credential_id",
          "collection_name",
          "enable_fulltext"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Qdrant 配置节点输出",
        "properties": {
          "api_key": {
            "description": "API key (used in cloud/authenticated modes)",
            "title": "API Key",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.ai.qdrant_config.outputs.api_key"
          },
          "collection_name": {
            "description": "Qdrant collection name",
            "title": "Collection Name",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.ai.qdrant_config.outputs.collection_name"
          },
          "credential_id": {
            "description": "Credential ID used, if any",
            "title": "Credential ID",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.ai.qdrant_config.outputs.credential_id"
          },
          "enable_fulltext": {
            "description": "Whether full-text search is enabled",
            "title": "Enable Fulltext",
            "type": "boolean",
            "x-i18n-key": "nodes.ai.qdrant_config.outputs.enable_fulltext"
          },
          "mode": {
            "description": "Qdrant deployment mode",
            "title": "Mode",
            "type": "string",
            "x-i18n-key": "nodes.ai.qdrant_config.outputs.mode"
          },
          "qdrant_config": {
            "additionalProperties": true,
            "description": "Complete Qdrant configuration (JSON object)",
            "type": "object",
            "x-i18n-key": "nodes.ai.qdrant_config.outputs.qdrant_config",
            "x-port": true
          },
          "url": {
            "description": "Qdrant gRPC endpoint URL",
            "title": "URL",
            "type": "string",
            "x-i18n-key": "nodes.ai.qdrant_config.outputs.url"
          }
        },
        "required": [
          "enable_fulltext",
          "mode",
          "qdrant_config",
          "url"
        ],
        "title": "QdrantConfigOutput",
        "type": "object",
        "x-collapsed-visible": [
          "collection_name",
          "qdrant_config"
        ],
        "x-field-order": [
          "mode",
          "url",
          "api_key",
          "collection_name",
          "enable_fulltext",
          "credential_id",
          "qdrant_config"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.ai.qdrant_config"
    },
    {
      "typeId": "tools/get_execution_trace",
      "name": "Get Execution Trace",
      "category": "tools",
      "description": "Read full execution trace from session_store by trace_key for LLM on-demand viewing",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "GetExecutionTrace 节点输入",
        "properties": {
          "trace_key": {
            "description": "Trace retrieval key, obtained from conversation history summary (format: session_id:turn)",
            "title": "Trace Key",
            "type": "string",
            "x-i18n-key": "nodes.tools.get_execution_trace.inputs.trace_key"
          }
        },
        "required": [
          "trace_key"
        ],
        "title": "GetTraceInput",
        "type": "object",
        "x-field-order": [
          "trace_key"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "GetExecutionTrace 节点输出",
        "properties": {
          "content": {
            "description": "Full execution trace content (empty string if not found)",
            "title": "Content",
            "type": "string",
            "x-i18n-key": "nodes.tools.get_execution_trace.outputs.content"
          },
          "found": {
            "description": "Whether the corresponding trace record was found",
            "title": "Found",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.get_execution_trace.outputs.found"
          }
        },
        "required": [
          "content",
          "found"
        ],
        "title": "GetTraceOutput",
        "type": "object",
        "x-field-order": [
          "content",
          "found"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.get_execution_trace"
    },
    {
      "typeId": "tools/edit_file",
      "name": "Edit File",
      "category": "tools",
      "description": "Replace file content by exact content matching. Supports multiple replacement operations; writes back atomically only when all succeed; any failure keeps original file unchanged.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "Replacement": {
            "description": "单个替换操作",
            "properties": {
              "end_line": {
                "description": "限制搜索范围的结束行(inclusive,可选)",
                "format": "uint32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "new_content": {
                "description": "替换后的内容(空字符串表示删除)",
                "type": "string"
              },
              "old_content": {
                "description": "要被替换的精确内容(必须与文件完全一致,包括空白和换行符)",
                "type": "string"
              },
              "start_line": {
                "description": "限制搜索范围的起始行(1-indexed,可选)",
                "format": "uint32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "required": [
              "new_content",
              "old_content"
            ],
            "type": "object"
          }
        },
        "properties": {
          "file_path": {
            "description": "Absolute file path to edit",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.edit_file.inputs.file_path"
          },
          "replacements": {
            "description": "List of replacement operations (executed in order)",
            "items": {
              "$ref": "#/definitions/Replacement"
            },
            "title": "Replacements",
            "type": "array",
            "x-i18n-key": "nodes.tools.edit_file.inputs.replacements"
          }
        },
        "required": [
          "file_path",
          "replacements"
        ],
        "title": "EditFileInput",
        "type": "object"
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "applied_count": {
            "description": "成功应用的替换数",
            "format": "uint32",
            "minimum": 0,
            "title": "Applied Count",
            "type": "integer",
            "x-i18n-key": "nodes.tools.edit_file.outputs.applied_count"
          },
          "error": {
            "description": "错误信息(一旦任意 replacement 失败即停止,文件保持原状)",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.edit_file.outputs.error"
          },
          "file_path": {
            "description": "编辑的文件路径",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.edit_file.outputs.file_path"
          },
          "total_lines_after": {
            "description": "编辑后总行数",
            "format": "uint32",
            "minimum": 0,
            "title": "Total Lines After",
            "type": "integer",
            "x-i18n-key": "nodes.tools.edit_file.outputs.total_lines_after"
          },
          "total_lines_before": {
            "description": "编辑前总行数",
            "format": "uint32",
            "minimum": 0,
            "title": "Total Lines Before",
            "type": "integer",
            "x-i18n-key": "nodes.tools.edit_file.outputs.total_lines_before"
          }
        },
        "required": [
          "applied_count",
          "file_path",
          "total_lines_after",
          "total_lines_before"
        ],
        "title": "EditFileOutput",
        "type": "object",
        "x-collapsed-visible": [
          "applied_count"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.edit_file"
    },
    {
      "typeId": "tools/code_shell",
      "name": "Shell Executor",
      "category": "tools",
      "description": "Run shell scripts in a bubblewrap sandbox (OS-namespace isolation: PID/IPC/UTS/network). FAIL-CLOSED: errors if bubblewrap is unavailable — no silent downgrade. Use for: curl, wget, system commands, file operations, pipeline processing, any external process. Do NOT use for pure computation (→ JS) or data transformation (→ Python). Requires allow_network=true for outbound HTTP. Example: {\"script\":\"curl -s 'wttr.in/Tokyo?format=3'\",\"allow_network\":true}",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "allow_filesystem": {
            "default": false,
            "description": "Whether to allow script to write files to workspace",
            "title": "Allow Filesystem Write",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.code_shell.inputs.allow_filesystem"
          },
          "allow_full_disk_readonly": {
            "default": false,
            "description": "Whether to allow read-only access to entire disk (for disk-wide search/file finding). Writing still requires allow_filesystem.",
            "title": "Allow Full Disk Read",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.code_shell.inputs.allow_full_disk_readonly"
          },
          "allow_network": {
            "default": false,
            "description": "Whether to allow network access (curl, HTTP requests etc. need to be true)",
            "title": "Allow Network",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.code_shell.inputs.allow_network"
          },
          "input": {
            "default": null,
            "description": "Input data (any JSON), accessible via $INPUT environment variable in script",
            "title": "Input",
            "x-i18n-key": "nodes.tools.code_shell.inputs.input"
          },
          "memory_mb": {
            "default": 128,
            "description": "Memory limit in MB. Enforced via prlimit under Bubblewrap. Default 128MB.",
            "format": "uint64",
            "maximum": 1024,
            "minimum": 16,
            "title": "Memory Limit (MB)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.code_shell.inputs.memory_mb"
          },
          "script": {
            "default": null,
            "description": "[Required] Shell script. Example: curl -s 'wttr.in/Tokyo?format=3'",
            "title": "Script",
            "type": "string",
            "x-control": "code-editor",
            "x-i18n-key": "nodes.tools.code_shell.inputs.script",
            "x-rows": 5
          },
          "timeout_ms": {
            "default": 5000,
            "description": "Timeout in milliseconds. Default 5000ms, max 300000ms.",
            "format": "uint64",
            "maximum": 300000,
            "minimum": 100,
            "title": "Timeout (ms)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.tools.code_shell.inputs.timeout_ms"
          },
          "workspace_name": {
            "default": null,
            "description": "Workspace name (e.g. project-alpha), only allows letters/digits/-/_.",
            "title": "Workspace Name",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.code_shell.inputs.workspace_name"
          }
        },
        "title": "CodeShellInput",
        "type": "object",
        "x-collapsed-visible": [
          "script"
        ],
        "x-field-order": [
          "input",
          "script",
          "workspace_name",
          "allow_filesystem",
          "allow_full_disk_readonly",
          "allow_network",
          "timeout_ms",
          "memory_mb"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "ExecutionMetrics": {
            "properties": {
              "duration_ms": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "input_size_bytes": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "output_size_bytes": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "peak_memory_bytes": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "runtime_type": {
                "type": "string"
              },
              "script_hash": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "duration_ms",
              "input_size_bytes",
              "output_size_bytes",
              "peak_memory_bytes",
              "runtime_type"
            ],
            "type": "object"
          }
        },
        "properties": {
          "isolation_level": {
            "description": "Actual isolation level used: bubblewrap > quickjs > python",
            "title": "Isolation Level",
            "type": "string",
            "x-i18n-key": "nodes.tools.code_shell.outputs.isolation_level"
          },
          "metrics": {
            "allOf": [
              {
                "$ref": "#/definitions/ExecutionMetrics"
              }
            ],
            "description": "Execution performance metrics",
            "title": "Metrics",
            "x-i18n-key": "nodes.tools.code_shell.outputs.metrics"
          },
          "result": {
            "description": "Script execution result",
            "title": "Result",
            "x-i18n-key": "nodes.tools.code_shell.outputs.result"
          },
          "stderr": {
            "description": "Standard error",
            "title": "Stderr",
            "type": "string",
            "x-i18n-key": "nodes.tools.code_shell.outputs.stderr"
          },
          "stdout": {
            "description": "Standard output",
            "title": "Stdout",
            "type": "string",
            "x-i18n-key": "nodes.tools.code_shell.outputs.stdout"
          },
          "warnings": {
            "description": "Script validation warnings",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array",
            "x-i18n-key": "nodes.tools.code_shell.outputs.warnings"
          }
        },
        "required": [
          "isolation_level",
          "metrics",
          "result",
          "stderr",
          "stdout",
          "warnings"
        ],
        "title": "CodeOutput",
        "type": "object",
        "x-collapsed-visible": [
          "result"
        ],
        "x-field-order": [
          "result",
          "isolation_level",
          "metrics",
          "stdout",
          "stderr",
          "warnings"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.code_shell"
    },
    {
      "typeId": "io/video_extract_frames",
      "name": "Video Extract Frames",
      "category": "io",
      "description": "Extract key frames from video at time intervals, outputs Base64 JPEG image array. Can connect to vision-enabled LLM nodes (GPT-4o, Claude 3, etc.). Requires ffmpeg installed.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "end_seconds": {
            "default": 0,
            "description": "Stop extracting at this second (0 means to the end of video)",
            "format": "uint32",
            "minimum": 0,
            "title": "End Seconds",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_frames.inputs.end_seconds"
          },
          "file_path": {
            "description": "Local absolute path of the video file (mp4/avi/mov/mkv/webm etc.)",
            "title": "File Path",
            "type": "string",
            "x-i18n-key": "nodes.io.video_extract_frames.inputs.file_path"
          },
          "height": {
            "default": 0,
            "description": "Output image height (pixels), 0 scales proportionally",
            "format": "uint32",
            "minimum": 0,
            "title": "Height",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_frames.inputs.height"
          },
          "include_timestamps": {
            "default": true,
            "description": "Whether to include timestamps in the frames array",
            "title": "Include Timestamps",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.io.video_extract_frames.inputs.include_timestamps"
          },
          "interval_seconds": {
            "default": 5,
            "description": "Extract one frame every N seconds, default 5",
            "format": "uint32",
            "minimum": 0,
            "title": "Interval Seconds",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_frames.inputs.interval_seconds"
          },
          "jpeg_quality": {
            "default": 85,
            "description": "JPEG compression quality 1-95, default 85",
            "format": "uint32",
            "minimum": 0,
            "title": "JPEG Quality",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_frames.inputs.jpeg_quality"
          },
          "max_frames": {
            "default": 20,
            "description": "Maximum number of frames to extract, default 20",
            "format": "uint32",
            "minimum": 0,
            "title": "Max Frames",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_frames.inputs.max_frames"
          },
          "start_seconds": {
            "default": 0,
            "description": "Start extracting from this second (0 means from the beginning)",
            "format": "uint32",
            "minimum": 0,
            "title": "Start Seconds",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_frames.inputs.start_seconds"
          },
          "width": {
            "default": 768,
            "description": "Output image width (pixels), 0 keeps original width",
            "format": "uint32",
            "minimum": 0,
            "title": "Width",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.io.video_extract_frames.inputs.width"
          }
        },
        "required": [
          "file_path"
        ],
        "title": "VideoExtractFramesInput",
        "type": "object",
        "x-field-order": [
          "file_path",
          "interval_seconds",
          "max_frames",
          "width",
          "height",
          "jpeg_quality",
          "include_timestamps",
          "start_seconds",
          "end_seconds"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "FrameInfo": {
            "description": "单帧信息",
            "properties": {
              "base64_jpeg": {
                "description": "Base64 编码的 JPEG 图片(data URI 格式,可直接嵌入 LLM 消息)",
                "type": "string"
              },
              "height": {
                "description": "图片高度(像素)",
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "index": {
                "description": "帧索引(从 0 开始)",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "timestamp_seconds": {
                "description": "对应视频时间戳(秒)",
                "format": "double",
                "type": "number"
              },
              "width": {
                "description": "图片宽度(像素)",
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "base64_jpeg",
              "height",
              "index",
              "timestamp_seconds",
              "width"
            ],
            "type": "object"
          }
        },
        "properties": {
          "frame_count": {
            "description": "Actual number of frames extracted",
            "format": "uint",
            "minimum": 0,
            "title": "Frame Count",
            "type": "integer",
            "x-i18n-key": "nodes.io.video_extract_frames.outputs.frame_count"
          },
          "frames": {
            "description": "Extracted frame list, each frame contains timestamp and Base64 JPEG image",
            "items": {
              "$ref": "#/definitions/FrameInfo"
            },
            "title": "Frames",
            "type": "array",
            "x-i18n-key": "nodes.io.video_extract_frames.outputs.frames"
          },
          "image_base64": {
            "description": "Base64 content of the first frame, can connect directly to vision-enabled LLM nodes",
            "title": "Image Base64",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.io.video_extract_frames.outputs.image_base64"
          },
          "video_duration_seconds": {
            "description": "Total video duration (seconds)",
            "format": "double",
            "title": "Video Duration Seconds",
            "type": [
              "number",
              "null"
            ],
            "x-i18n-key": "nodes.io.video_extract_frames.outputs.video_duration_seconds"
          }
        },
        "required": [
          "frame_count",
          "frames"
        ],
        "title": "VideoExtractFramesOutput",
        "type": "object",
        "x-collapsed-visible": [
          "image_base64"
        ],
        "x-field-order": [
          "frames",
          "frame_count",
          "video_duration_seconds",
          "image_base64"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.io.video_extract_frames"
    },
    {
      "typeId": "agent/react_agent",
      "name": "ReAct Agent",
      "category": "agent",
      "description": "Intelligent decision agent that automatically plans, executes and evaluates tasks",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input for ReactAgent node.",
        "properties": {
          "context": {
            "additionalProperties": true,
            "default": null,
            "description": "Existing AgentContext (optional, for continuing historical conversation)",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.agent.react_agent.inputs.context",
            "x-port": true
          },
          "llm_config": {
            "additionalProperties": true,
            "description": "LLM configuration (JSON string or object)",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.agent.react_agent.inputs.llm_config",
            "x-port": true
          },
          "max_checkpoints": {
            "default": 3,
            "description": "Max checkpoint count (LLM may request extension when iterations exhausted)",
            "format": "uint",
            "minimum": 0,
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.agent.react_agent.inputs.max_checkpoints"
          },
          "max_iterations": {
            "default": 3,
            "description": "Maximum number of iterations",
            "format": "uint",
            "minimum": 0,
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.agent.react_agent.inputs.max_iterations"
          },
          "max_review_rounds": {
            "default": 1,
            "description": "Max LLM review rounds",
            "format": "uint",
            "minimum": 0,
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.agent.react_agent.inputs.max_review_rounds"
          },
          "min_tool_calls_for_skill": {
            "default": 3,
            "description": "Min successful tool calls to emit skill summary (0 = disabled)",
            "format": "uint",
            "minimum": 0,
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.agent.react_agent.inputs.min_tool_calls_for_skill"
          },
          "reviewer_llm_config": {
            "additionalProperties": true,
            "default": null,
            "description": "Reviewer LLM configuration (optional, falls back to main LLM config)",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.agent.react_agent.inputs.reviewer_llm_config",
            "x-port": true
          },
          "reviewer_prompt": {
            "default": null,
            "description": "Reviewer criteria / prompt (used when LLM evaluation is enabled)",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.agent.react_agent.inputs.reviewer_prompt"
          },
          "system_prompt": {
            "default": null,
            "description": "Custom system prompt (overrides default system prompt)",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.agent.react_agent.inputs.system_prompt"
          },
          "task": {
            "default": null,
            "description": "Task description to accomplish (optional, auto-extracted from context conversation history if empty)",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.agent.react_agent.inputs.task"
          },
          "tools": {
            "default": [],
            "description": "Available tools (populated from connected tool nodes via tools port)",
            "title": "Tools",
            "type": "array",
            "x-dynamic-array": {
              "allowAdd": true,
              "allowRemove": true,
              "maxPorts": 20,
              "minPorts": 0,
              "portPrefix": "tool"
            },
            "x-i18n-key": "nodes.agent.react_agent.inputs.tools",
            "x-tool-options": [
              {
                "description": "Call other workflows as sub-workflows, supports file path or workflow ID, passes input parameters and waits for completion",
                "label": "Sub Workflow Tool",
                "value": "tools/subflow"
              },
              {
                "description": "Search text in files or directories. Supports literal/regex patterns, case-insensitive, filename glob filtering, exclude paths, result context lines. Max 100 results.",
                "label": "Search Files",
                "value": "tools/search_files"
              },
              {
                "description": "Read file content within specified line range. Always returns total_lines and eof marker to help LLM perceive file full picture and prevent hallucination. Max 500 lines per request.",
                "label": "View File",
                "value": "tools/view_file"
              },
              {
                "description": "List directory contents, return structured entry list (filename, size, modification time, type, etc.). Supports glob filtering and recursive depth control, max 200 entries.",
                "label": "List Directory",
                "value": "tools/list_directory"
              },
              {
                "description": "Batch apply document operations (insert/update/delete/move)",
                "label": "Apply Document Operations",
                "value": "document/apply_ops"
              },
              {
                "description": "Operate real emails via IMAP/SMTP protocols: send, read, search, move, mark, reply, forward and more",
                "label": "Mail Tool",
                "value": "tools/mail"
              },
              {
                "description": "Get file or directory metadata (size, line count, modification time, binary or not, etc.) without reading file content.",
                "label": "File Info",
                "value": "tools/file_info"
              },
              {
                "description": "Run shell scripts in a bubblewrap sandbox (OS-namespace isolation: PID/IPC/UTS/network). FAIL-CLOSED: errors if bubblewrap is unavailable — no silent downgrade. Use for: curl, wget, system commands, file operations, pipeline processing, any external process. Do NOT use for pure computation (→ JS) or data transformation (→ Python). Requires allow_network=true for outbound HTTP. Example: {\"script\":\"curl -s 'wttr.in/Tokyo?format=3'\",\"allow_network\":true}",
                "label": "Shell Executor",
                "value": "tools/code_shell"
              },
              {
                "description": "Run Python 3 scripts (native python3, NO OS-level isolation — trusted environment only). FAIL-CLOSED: errors if python3 runtime is unavailable. Use for: algorithms, text processing, data transformation, scientific computing. Do NOT use for network requests (→ Shell) or simple JSON/string transforms (→ JS). Network access is disabled on this node by design. Example: {\"script\":\"result = sum(input['values'])\",\"input\":{\"values\":[1,2,3]}}",
                "label": "Python Executor",
                "value": "tools/code_python"
              },
              {
                "description": "Execute commands on remote hosts via SSH with a built-in approval gate. Risk-classifies commands, enforces read-only policy, and surfaces 4 distinct rejection reasons (rejected/skipped/timed_out/policy_denied) so agents can replan correctly.",
                "label": "SSH Executor",
                "value": "tools/ssh"
              },
              {
                "description": "Use this skill when the online UI chat assistant must guide a user through designing a ChengOS workflow and generate an importable workflow JSON file. The assistant uses Workflow API endpoints for templates, node schemas, and LLM model lists.",
                "label": "Workflow Json Builder",
                "value": "workflow-json-builder"
              },
              {
                "description": "Unified document operation toolkit, select one of 4 operations via `operation` field.Operations not enabled in node config return errors immediately, no side effects.\n\n[query] Query document content (read-only).Required: document_id.Optional: as_markdown (return Markdown format, default false), include_content (include full block content, default true).Returns: document_id, title, blocks, markdown, plain_text, block_count, character_count.\n\n[format_for_llm] Format document for LLM use (read-only).Required: document_id.Optional: priority_filter (all/high_only/critical_only/normal_and_above),tag_filter (comma-separated), sort_order (original/priority_desc/priority_asc),output_format (markdown/plain_text/structured), include_metadata (default true),max_chars (0 for unlimited).Returns: formatted_content, title, block_count, filtered_block_count, character_count, truncated.\n\n[update_block] Update specific block content (medium side-effect, requires node enable).Required: document_id, block_id, content.Optional: block_type, language (code block language), priority, tags (comma-separated).Returns: block_id, block_type, document_version.\n\n[create] Create new document in workspace (medium side-effect, requires node enable).workspace_id from node static config, LLM doesn't need to fill.Optional: title (document title), content (initial content), block_type (default paragraph),priority (default normal), tags (comma-separated).Returns: document_id, title, root_block_id.",
                "label": "Document Operations Hub",
                "value": "document/ops_hub"
              },
              {
                "description": "Build context information for LLM document editing",
                "label": "Build LLM Context",
                "value": "document/build_llm_context"
              },
              {
                "description": "Read-only query for workflow definitions, node schemas, and execution status. list_workflows=list workflows (name/tag filter, pagination), get_workflow=get workflow details (nodes/edges/tags), list_node_types=list all node types, get_node_schema=get node input/output schema, get_execution=query execution status and node outputs by execution_id, list_executions=list execution history for a workflow (requires workflow_id)",
                "label": "Workflow Inspector",
                "value": "tools/workflow_inspect"
              },
              {
                "description": "Batch apply table record insert, update, delete operations",
                "label": "Apply Table Operations",
                "value": "table/apply_record_ops"
              },
              {
                "description": "Directly list, create, update, pause, resume, cancel, and inspect scheduled tasks",
                "label": "Schedule Manager",
                "value": "tools/schedule"
              },
              {
                "description": "Send HTTP requests to specified URL, supports manual mode and LLM mode",
                "label": "HTTP Tool",
                "value": "tools/http"
              },
              {
                "description": "File operations aggregate node: only one node needed on canvas, control Agent's available file operation capabilities via toggle switches.",
                "label": "File Operations Hub",
                "value": "tools/file_ops_hub"
              },
              {
                "description": "Create new file or overwrite/append existing file. Uses atomic write (temp file + rename) to prevent file corruption from interrupted writes.",
                "label": "Write File",
                "value": "tools/write_file"
              },
              {
                "description": "Use this skill when the user has questions about building, debugging, or understanding ChengOS workflows — including node selection, port wiring, field configuration, error troubleshooting, and workflow pattern recommendations.",
                "label": "Workflow Helper",
                "value": "workflow-helper"
              },
              {
                "description": "Replace file content by exact content matching (old_content → new_content). Supports multiple replacement operations; writes back atomically only when all succeed; any failure keeps original file unchanged.",
                "label": "Edit File",
                "value": "tools/edit_file"
              },
              {
                "description": "Run JavaScript in QuickJS engine sandbox (NO syscalls, NO network, NO filesystem — fully isolated). FAIL-CLOSED: errors if QuickJS is unavailable. Use for: pure computation, JSON/object transformation, string manipulation, math. Do NOT use for network requests (→ Shell) or complex algorithms needing libraries (→ Python). Just provide script and input. Example: {\"script\":\"input.values.reduce((a,b)=>a+b,0)\",\"input\":{\"values\":[1,2,3]}}",
                "label": "JavaScript Executor",
                "value": "tools/code_js"
              },
              {
                "description": "Connect one or more MCP servers in one place. Discover tools, manage visibility, and call tools with unified output.",
                "label": "MCP Hub",
                "value": "tools/mcp_hub"
              },
              {
                "description": "Delete file (high side-effect, irreversible). Only allows deleting files, not directories. When dry_run=true, performs all checks but does not actually delete, used to verify deletability.",
                "label": "Delete File",
                "value": "tools/delete_file"
              }
            ]
          },
          "use_function_calling": {
            "default": true,
            "description": "Use native function calling mode",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.agent.react_agent.inputs.use_function_calling"
          },
          "use_llm_evaluation": {
            "default": false,
            "description": "Enable LLM evaluation",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.agent.react_agent.inputs.use_llm_evaluation"
          },
          "user_message": {
            "default": null,
            "description": "User additional instruction (prepended to task, e.g.: Before starting, read SKILLS_INDEX.md first)",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.agent.react_agent.inputs.user_message"
          }
        },
        "required": [
          "llm_config"
        ],
        "title": "ReactAgentInput",
        "type": "object",
        "x-collapsed-visible": [
          "context",
          "system_prompt",
          "llm_config",
          "max_iterations",
          "tools",
          "tool_0",
          "tool_1",
          "tool_2",
          "tool_3",
          "tool_4",
          "tool_5",
          "tool_6",
          "tool_7",
          "tool_8",
          "tool_9",
          "use_function_calling"
        ],
        "x-field-order": [
          "context",
          "task",
          "llm_config",
          "max_iterations",
          "tools",
          "use_function_calling",
          "use_llm_evaluation",
          "max_checkpoints",
          "system_prompt",
          "user_message",
          "reviewer_prompt",
          "reviewer_llm_config",
          "max_review_rounds",
          "min_tool_calls_for_skill"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AgentContext": {
            "description": "Agent execution context.\n\nContains agent-specific information such as conversation history, iteration count, session tracking, and custom metadata.\n\n# Metadata Conventions\n\nThe `session_id` field is a first-class field for session tracking: - **Initialization**: Should be set by the workflow engine or the first agent node - **Persistence**: Memory nodes (redis/postgres/window) use it for storage keys - **Logging**: LLM and memory nodes include it in tracing logs for debugging - **Propagation**: All nodes should preserve the session_id across the execution chain\n\nAdditional metadata can be stored in the `metadata` HashMap for custom use cases.\n\n# Examples\n\n``` use cheng_nodes::nodes::builtin::agent::base::context::AgentContext; use cheng_llm::types::ChatMessage;\n\nlet context = AgentContext::new() .with_session_id(\"user123_conversation_456\") .with_history(vec![ChatMessage::user(\"Hello\")]) .with_max_iterations(5); ```",
            "properties": {
              "history": {
                "default": [],
                "description": "Conversation history (messages exchanged so far)",
                "items": {
                  "$ref": "#/definitions/ChatMessage"
                },
                "type": "array"
              },
              "iteration": {
                "default": 0,
                "description": "Current iteration count (for ReAct loops, etc.)",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "max_iterations": {
                "default": 10,
                "description": "Maximum iterations allowed",
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "metadata": {
                "additionalProperties": true,
                "default": {},
                "description": "Custom metadata (for extensibility)\n\nUse this for additional context that doesn't fit into standard fields. Examples: user preferences, workflow-specific data, feature flags.",
                "type": "object"
              },
              "preview_content": {
                "description": "预览内容(所有消息合并后的纯文本,供预览节点直接展示)\n\n由合并节点(ContextMergeNode)等聚合节点填写,优先于 history 展示。",
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "default": "session_2c9d131b-4cd2-4e74-9adf-240f28ce965f",
                "description": "Session identifier for tracking conversations across nodes and storage\n\nThis should be a unique identifier for the conversation session. Format examples: \"user123_session456\", \"uuid-v4\", \"workflow_exec_789\"",
                "type": "string"
              }
            },
            "type": "object"
          },
          "ChatContentPart": {
            "description": "A single rich content part in a message.\n\nOpenAI Chat Completions accepts either plain text or an array of content parts for user messages. This enum keeps the message model backward compatible while making image/audio/file inputs expressible.",
            "oneOf": [
              {
                "description": "Plain text content.",
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Image input, either a normal URL or a base64 data URL.",
                "properties": {
                  "image_url": {
                    "$ref": "#/definitions/ImageUrlContent"
                  },
                  "type": {
                    "enum": [
                      "image_url"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "image_url",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Audio input for speech recognition / audio reasoning.",
                "properties": {
                  "input_audio": {
                    "$ref": "#/definitions/InputAudioContent"
                  },
                  "type": {
                    "enum": [
                      "input_audio"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "input_audio",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "File input for supported document reasoning models.",
                "properties": {
                  "file": {
                    "$ref": "#/definitions/FileContent"
                  },
                  "type": {
                    "enum": [
                      "file"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "file",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "ChatMessage": {
            "description": "A single message in a conversation.\n\n# Examples\n\n``` use cheng_llm::types::ChatMessage;\n\nlet system_msg = ChatMessage::system(\"You are a helpful assistant.\"); let user_msg = ChatMessage::user(\"What is Rust?\"); let assistant_msg = ChatMessage::assistant(\"Rust is a systems programming language.\"); ```",
            "properties": {
              "content": {
                "type": "string"
              },
              "parts": {
                "description": "Optional rich content parts for multimodal providers.\n\nWhen present, `content` is treated as the leading text prompt and the parts are serialized as the provider-specific content array.",
                "items": {
                  "$ref": "#/definitions/ChatContentPart"
                },
                "type": [
                  "array",
                  "null"
                ]
              },
              "role": {
                "$ref": "#/definitions/Role"
              }
            },
            "required": [
              "content",
              "role"
            ],
            "type": "object"
          },
          "FileContent": {
            "description": "File input payload for OpenAI-style chat content parts.",
            "properties": {
              "file_data": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "file_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "filename": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "ImageUrlContent": {
            "description": "Image input payload for OpenAI-style chat content parts.",
            "properties": {
              "detail": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "url": {
                "type": "string"
              }
            },
            "required": [
              "url"
            ],
            "type": "object"
          },
          "InputAudioContent": {
            "description": "Audio input payload for OpenAI-style chat content parts.",
            "properties": {
              "data": {
                "type": "string"
              },
              "format": {
                "type": "string"
              }
            },
            "required": [
              "data",
              "format"
            ],
            "type": "object"
          },
          "Role": {
            "description": "Message role in a conversation.",
            "enum": [
              "system",
              "user",
              "assistant"
            ],
            "type": "string"
          }
        },
        "description": "Output from ReactAgent node.",
        "properties": {
          "context": {
            "additionalProperties": true,
            "description": "Agent context (contains conversation history)",
            "title": "Agent Context",
            "type": "object",
            "x-i18n-key": "nodes.agent.react_agent.outputs.context",
            "x-port": true
          },
          "final_answer": {
            "description": "Final answer",
            "title": "Final Answer",
            "type": "string",
            "x-i18n-key": "nodes.agent.react_agent.outputs.final_answer",
            "x-port": true
          },
          "iterations_used": {
            "description": "Number of iterations executed",
            "format": "uint",
            "minimum": 0,
            "title": "Iterations Used",
            "type": "integer",
            "x-i18n-key": "nodes.agent.react_agent.outputs.iterations_used"
          },
          "requires_review": {
            "description": "Whether human review is required",
            "title": "Requires Review",
            "type": "boolean",
            "x-i18n-key": "nodes.agent.react_agent.outputs.requires_review"
          },
          "session_id": {
            "description": "Session ID (consistent with context.session_id, convenient for downstream direct connection)",
            "title": "Session ID",
            "type": "string",
            "x-i18n-key": "nodes.agent.react_agent.outputs.session_id",
            "x-port": true
          },
          "skill_summary": {
            "anyOf": [
              {
                "$ref": "#/definitions/AgentContext"
              },
              {
                "type": "null"
              }
            ],
            "description": "Lean AgentContext for skill distillation (conditional: absent when not needed)",
            "title": "Skill Summary",
            "x-i18n-key": "nodes.agent.react_agent.outputs.skill_summary",
            "x-runtime-conditional": true
          },
          "status": {
            "description": "Status message",
            "title": "Status",
            "type": "string",
            "x-i18n-key": "nodes.agent.react_agent.outputs.status"
          },
          "success": {
            "description": "Whether task was completed successfully",
            "title": "Success",
            "type": "boolean",
            "x-i18n-key": "nodes.agent.react_agent.outputs.success"
          },
          "total_tokens": {
            "description": "Cumulative token consumption",
            "format": "uint32",
            "minimum": 0,
            "title": "Total Tokens",
            "type": "integer",
            "x-i18n-key": "nodes.agent.react_agent.outputs.total_tokens"
          },
          "trace": {
            "description": "Execution trace",
            "title": "Trace",
            "type": "string",
            "x-i18n-key": "nodes.agent.react_agent.outputs.trace",
            "x-port": true
          }
        },
        "required": [
          "context",
          "final_answer",
          "iterations_used",
          "requires_review",
          "session_id",
          "status",
          "success",
          "total_tokens",
          "trace"
        ],
        "title": "ReactAgentOutput",
        "type": "object",
        "x-collapsed-visible": [
          "final_answer",
          "context"
        ],
        "x-field-order": [
          "final_answer",
          "context",
          "session_id",
          "trace",
          "total_tokens",
          "iterations_used",
          "success",
          "status",
          "requires_review",
          "skill_summary"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.agent.react_agent"
    },
    {
      "typeId": "document/update_block",
      "name": "Update Document Block",
      "category": "document",
      "description": "Update content or type of a specific block in document, supports AgentContext pass-through",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input for DocumentUpdateBlockNode",
        "properties": {
          "block_id": {
            "description": "ID of the block to update.",
            "title": "Block Id",
            "type": "string",
            "x-i18n-key": "nodes.document.update_block.inputs.block_id"
          },
          "block_type": {
            "default": null,
            "description": "New block type (optional, keeps existing if not provided).",
            "title": "Block Type",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.update_block.inputs.block_type"
          },
          "content": {
            "description": "New content for the block.",
            "type": "string",
            "x-i18n-key": "nodes.document.update_block.inputs.content"
          },
          "context": {
            "additionalProperties": true,
            "default": null,
            "description": "AgentContext port",
            "title": "Context",
            "type": "object",
            "x-i18n-key": "nodes.document.update_block.inputs.context",
            "x-port": true
          },
          "document_id": {
            "description": "Select document to update",
            "type": "string",
            "x-api-endpoint": "/api/v1/documents?limit=200",
            "x-cache-key": "static_select:/api/v1/documents?limit=200",
            "x-control": "dynamic-select",
            "x-i18n-key": "nodes.document.update_block.inputs.document_id"
          },
          "language": {
            "default": null,
            "description": "Language for code blocks (optional).",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.update_block.inputs.language"
          },
          "priority": {
            "default": null,
            "description": "Block priority",
            "enum": [
              "low",
              "normal",
              "medium",
              "high",
              "critical"
            ],
            "options": [
              {
                "label": "low",
                "value": "low"
              },
              {
                "label": "normal",
                "value": "normal"
              },
              {
                "label": "medium",
                "value": "medium"
              },
              {
                "label": "high",
                "value": "high"
              },
              {
                "label": "critical",
                "value": "critical"
              }
            ],
            "title": "Priority",
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.document.update_block.inputs.priority"
          },
          "tags": {
            "default": null,
            "description": "Block tags (comma-separated)",
            "title": "Tags",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.update_block.inputs.tags"
          }
        },
        "required": [
          "block_id",
          "content",
          "document_id"
        ],
        "title": "DocumentUpdateBlockInput",
        "type": "object",
        "x-field-order": [
          "context",
          "document_id",
          "block_id",
          "content",
          "block_type",
          "language",
          "priority",
          "tags"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Output from DocumentUpdateBlockNode",
        "properties": {
          "block_id": {
            "description": "Updated block ID.",
            "title": "Block Id",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.update_block.outputs.block_id"
          },
          "block_type": {
            "description": "Updated block type.",
            "title": "Block Type",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.update_block.outputs.block_type"
          },
          "content": {
            "description": "Updated content.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.update_block.outputs.content"
          },
          "context": {
            "additionalProperties": true,
            "description": "AgentContext port",
            "title": "Context",
            "type": "object",
            "x-i18n-key": "nodes.document.update_block.outputs.context",
            "x-port": true
          },
          "document_version": {
            "description": "New document version after update.",
            "format": "uint32",
            "minimum": 0,
            "title": "Document Version",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.document.update_block.outputs.document_version"
          },
          "error": {
            "description": "Error message if update failed.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.document.update_block.outputs.error"
          },
          "string": {
            "description": "Formatted success message with document_id and block_id",
            "type": "string",
            "x-i18n-key": "nodes.document.update_block.outputs.string"
          },
          "success": {
            "description": "Whether the update was successful.",
            "type": "boolean",
            "x-i18n-key": "nodes.document.update_block.outputs.success"
          }
        },
        "required": [
          "context",
          "string",
          "success"
        ],
        "title": "DocumentUpdateBlockOutput",
        "type": "object",
        "x-collapsed-visible": [
          "context",
          "string"
        ],
        "x-field-order": [
          "context",
          "string",
          "success",
          "block_id",
          "block_type",
          "content",
          "document_version",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.document.update_block"
    },
    {
      "typeId": "tools/search_files",
      "name": "Search Files",
      "category": "tools",
      "description": "Search text in files or directories, like grep, returns structured matching results. Supports regex, case-insensitive, glob filtering and context lines.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "case_insensitive": {
            "default": false,
            "description": "Whether to ignore case, default false",
            "title": "Case Insensitive",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.search_files.inputs.case_insensitive"
          },
          "context_lines": {
            "description": "Show N lines of context before/after each match (0-3), default 0",
            "format": "uint32",
            "minimum": 0,
            "title": "Context Lines",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.search_files.inputs.context_lines"
          },
          "exclude_patterns": {
            "description": "Exclude filename glob list (e.g. [\"*.bak\", \"target/**\"])",
            "items": {
              "type": "string"
            },
            "title": "Exclude Patterns",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.tools.search_files.inputs.exclude_patterns"
          },
          "include_patterns": {
            "description": "Filename glob filter list (e.g. [\"*.rs\", \"*.toml\"]), only search matching files",
            "items": {
              "type": "string"
            },
            "title": "Include Patterns",
            "type": [
              "array",
              "null"
            ],
            "x-i18n-key": "nodes.tools.search_files.inputs.include_patterns"
          },
          "is_regex": {
            "default": false,
            "description": "Whether query is a regex pattern, default false",
            "title": "Is Regex",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.search_files.inputs.is_regex"
          },
          "max_results": {
            "description": "Maximum number of results, default 50, max 100",
            "format": "uint32",
            "minimum": 0,
            "title": "Max Results",
            "type": [
              "integer",
              "null"
            ],
            "x-i18n-key": "nodes.tools.search_files.inputs.max_results"
          },
          "query": {
            "description": "Search keyword or regular expression",
            "title": "Query",
            "type": "string",
            "x-i18n-key": "nodes.tools.search_files.inputs.query"
          },
          "search_path": {
            "description": "Starting path for search (file or directory absolute path)",
            "title": "Search Path",
            "type": "string",
            "x-i18n-key": "nodes.tools.search_files.inputs.search_path"
          }
        },
        "required": [
          "query",
          "search_path"
        ],
        "title": "SearchFilesInput",
        "type": "object"
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "SearchMatch": {
            "description": "单个搜索匹配结果",
            "properties": {
              "context_after": {
                "description": "后 N 行上下文(context_lines > 0 时)",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "context_before": {
                "description": "前 N 行上下文(context_lines > 0 时)",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "file_path": {
                "description": "匹配文件绝对路径",
                "type": "string"
              },
              "line_content": {
                "description": "匹配行内容(去除尾部空白)",
                "type": "string"
              },
              "line_number": {
                "description": "1-indexed 行号",
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "context_after",
              "context_before",
              "file_path",
              "line_content",
              "line_number"
            ],
            "type": "object"
          }
        },
        "properties": {
          "elapsed_ms": {
            "description": "操作耗时(毫秒)",
            "format": "uint64",
            "minimum": 0,
            "title": "Elapsed Ms",
            "type": "integer",
            "x-i18n-key": "nodes.tools.search_files.outputs.elapsed_ms"
          },
          "error": {
            "description": "错误信息",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.search_files.outputs.error"
          },
          "matches": {
            "description": "匹配结果列表(按文件路径 + 行号升序)",
            "items": {
              "$ref": "#/definitions/SearchMatch"
            },
            "type": "array",
            "x-i18n-key": "nodes.tools.search_files.outputs.matches"
          },
          "searched_files": {
            "description": "实际扫描的文件数",
            "format": "uint32",
            "minimum": 0,
            "title": "Searched Files",
            "type": "integer",
            "x-i18n-key": "nodes.tools.search_files.outputs.searched_files"
          },
          "total_matches": {
            "description": "返回的匹配数",
            "format": "uint32",
            "minimum": 0,
            "title": "Total Matches",
            "type": "integer",
            "x-i18n-key": "nodes.tools.search_files.outputs.total_matches"
          },
          "truncated": {
            "description": "是否因达到 max_results 上限而截断",
            "type": "boolean",
            "x-i18n-key": "nodes.tools.search_files.outputs.truncated"
          }
        },
        "required": [
          "elapsed_ms",
          "matches",
          "searched_files",
          "total_matches",
          "truncated"
        ],
        "title": "SearchFilesOutput",
        "type": "object",
        "x-collapsed-visible": [
          "matches"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.search_files"
    },
    {
      "typeId": "workspace/hub",
      "name": "Workspace Hub",
      "category": "workspace",
      "description": "Select existing workspace or create new one with optional directory tree",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input for WorkspaceHubNode",
        "properties": {
          "create_folders": {
            "default": true,
            "description": "Create directory tree (create mode, default: true)",
            "title": "Create Folders",
            "type": "boolean",
            "x-conditional": {
              "field": "mode",
              "values": [
                "create"
              ]
            },
            "x-i18n-key": "nodes.workspace.hub.inputs.create_folders"
          },
          "description": {
            "default": null,
            "description": "Workspace description (create mode, optional)",
            "title": "Description",
            "type": [
              "string",
              "null"
            ],
            "x-conditional": {
              "field": "mode",
              "values": [
                "create"
              ]
            },
            "x-i18n-key": "nodes.workspace.hub.inputs.description"
          },
          "mode": {
            "default": "select",
            "description": "select: Select existing workspace; create: Create new workspace",
            "enum": [
              "select",
              "create"
            ],
            "options": [
              {
                "label": "select",
                "value": "select"
              },
              {
                "label": "create",
                "value": "create"
              }
            ],
            "type": "string",
            "x-control": "select",
            "x-i18n-key": "nodes.workspace.hub.inputs.mode"
          },
          "name": {
            "default": null,
            "description": "New workspace name (create mode)",
            "title": "Name",
            "type": [
              "string",
              "null"
            ],
            "x-conditional": {
              "field": "mode",
              "values": [
                "create"
              ]
            },
            "x-i18n-key": "nodes.workspace.hub.inputs.name"
          },
          "workspace_id": {
            "default": null,
            "description": "Select existing workspace (select mode)",
            "type": "string",
            "x-api-endpoint": "/api/v1/workspaces?limit=200",
            "x-cache-key": "static_select:/api/v1/workspaces?limit=200",
            "x-conditional": {
              "field": "mode",
              "values": [
                "select"
              ]
            },
            "x-control": "dynamic-select",
            "x-i18n-key": "nodes.workspace.hub.inputs.workspace_id"
          }
        },
        "title": "WorkspaceHubInput",
        "type": "object",
        "x-field-order": [
          "mode",
          "workspace_id",
          "name",
          "description",
          "create_folders"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Output from WorkspaceHubNode",
        "properties": {
          "created": {
            "description": "Whether this was a newly created workspace (true) or an existing one (false).",
            "type": "boolean",
            "x-i18n-key": "nodes.workspace.hub.outputs.created"
          },
          "error": {
            "description": "Error message if the operation failed.",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.workspace.hub.outputs.error"
          },
          "folders_created": {
            "description": "Whether the directory tree was created. Only meaningful when `created = true` and `create_folders` was enabled.",
            "title": "Folders Created",
            "type": "boolean",
            "x-i18n-key": "nodes.workspace.hub.outputs.folders_created"
          },
          "success": {
            "description": "Whether the workspace operation (create or select) succeeded.",
            "type": "boolean",
            "x-i18n-key": "nodes.workspace.hub.outputs.success"
          },
          "warnings": {
            "description": "Warnings from bootstrap (non-fatal issues).",
            "items": {
              "type": "string"
            },
            "type": "array",
            "x-i18n-key": "nodes.workspace.hub.outputs.warnings"
          },
          "workspace_id": {
            "description": "ID of the selected or created workspace.",
            "title": "Workspace Id",
            "type": "string",
            "x-i18n-key": "nodes.workspace.hub.outputs.workspace_id"
          },
          "workspace_name": {
            "description": "Name of the workspace.",
            "title": "Workspace Name",
            "type": "string",
            "x-i18n-key": "nodes.workspace.hub.outputs.workspace_name"
          }
        },
        "required": [
          "created",
          "folders_created",
          "success",
          "warnings",
          "workspace_id",
          "workspace_name"
        ],
        "title": "WorkspaceHubOutput",
        "type": "object",
        "x-collapsed-visible": [
          "workspace_id",
          "workspace_name",
          "folders_created"
        ],
        "x-field-order": [
          "workspace_id",
          "workspace_name",
          "created",
          "success",
          "folders_created",
          "warnings",
          "error"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.workspace.hub"
    },
    {
      "typeId": "chat/input",
      "name": "Chat Input Node",
      "category": "chat",
      "description": "Receive multi-modal input (text, images, files, etc.), process and send to downstream nodes",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "ChatInputNode 输入",
        "properties": {
          "conversation_id": {
            "default": null,
            "description": "Conversation ID (optional), generated at entry and passed through to all downstream nodes",
            "title": "Conversation ID",
            "type": "string",
            "x-i18n-key": "nodes.chat.input.inputs.conversation_id",
            "x-port": true
          },
          "enable_ocr": {
            "default": false,
            "description": "Enable OCR for images",
            "title": "Enable OCR",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.chat.input.inputs.enable_ocr"
          },
          "max_file_size_mb": {
            "default": 50,
            "description": "Maximum file size (MB)",
            "format": "uint64",
            "maximum": 500,
            "minimum": 1,
            "title": "Max File Size (MB)",
            "type": "integer",
            "x-control": "number",
            "x-i18n-key": "nodes.chat.input.inputs.max_file_size_mb"
          },
          "merge_strategy": {
            "default": "per_file",
            "description": "Multi-input merge strategy",
            "oneOf": [
              {
                "description": "合并所有消息为一个包",
                "enum": [
                  "merge_all"
                ],
                "type": "string"
              },
              {
                "description": "每个文件单独一个包",
                "enum": [
                  "per_file"
                ],
                "type": "string"
              },
              {
                "description": "每行单独一个包",
                "enum": [
                  "per_line"
                ],
                "type": "string"
              }
            ],
            "title": "Merge Strategy",
            "x-control": "select",
            "x-i18n-key": "nodes.chat.input.inputs.merge_strategy"
          },
          "model_override": {
            "default": null,
            "description": "Model override (format: credential_id::model_name)",
            "title": "Model Override",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.chat.input.inputs.model_override"
          },
          "raw_input": {
            "description": "Raw input payload (JSON format)",
            "title": "Raw Input",
            "type": "string",
            "x-control": "textarea",
            "x-i18n-key": "nodes.chat.input.inputs.raw_input",
            "x-port": true
          },
          "stream_mode": {
            "default": false,
            "description": "Enable streaming send",
            "title": "Stream Mode",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.chat.input.inputs.stream_mode"
          },
          "user_message_rich": {
            "additionalProperties": true,
            "default": null,
            "description": "Optional rich user message from upstream nodes",
            "title": "User Message Rich",
            "type": "object",
            "x-i18n-key": "nodes.chat.input.inputs.user_message_rich",
            "x-port": true
          },
          "workspace_id": {
            "default": null,
            "description": "Workspace ID (optional), passed to chat/memory for per-workspace chat isolation",
            "title": "Workspace ID",
            "type": "string",
            "x-i18n-key": "nodes.chat.input.inputs.workspace_id",
            "x-port": true
          }
        },
        "required": [
          "raw_input"
        ],
        "title": "ChatInputNodeInput",
        "type": "object",
        "x-field-order": [
          "raw_input",
          "user_message_rich",
          "conversation_id",
          "workspace_id",
          "stream_mode",
          "enable_ocr",
          "merge_strategy",
          "max_file_size_mb",
          "model_override"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AppendMode": {
            "description": "追加模式",
            "oneOf": [
              {
                "description": "平滑追加(带动画)",
                "enum": [
                  "smooth"
                ],
                "type": "string"
              },
              {
                "description": "即时追加",
                "enum": [
                  "instant"
                ],
                "type": "string"
              }
            ]
          },
          "ChatAppendPayload": {
            "description": "ChatAppend 事件载荷",
            "properties": {
              "append_mode": {
                "allOf": [
                  {
                    "$ref": "#/definitions/AppendMode"
                  }
                ],
                "description": "追加模式"
              },
              "packets": {
                "description": "要追加的消息列表",
                "items": {
                  "$ref": "#/definitions/MessagePacket"
                },
                "type": "array"
              },
              "scroll_hint": {
                "allOf": [
                  {
                    "$ref": "#/definitions/ScrollHint"
                  }
                ],
                "description": "滚动提示"
              }
            },
            "required": [
              "append_mode",
              "packets",
              "scroll_hint"
            ],
            "type": "object"
          },
          "ChatMetaPayload": {
            "description": "ChatMeta 事件载荷",
            "properties": {
              "action": {
                "allOf": [
                  {
                    "$ref": "#/definitions/MetaAction"
                  }
                ],
                "description": "元操作类型"
              },
              "data": {
                "description": "附加数据"
              }
            },
            "required": [
              "action"
            ],
            "type": "object"
          },
          "ChatPatchPayload": {
            "description": "ChatPatch 事件载荷",
            "properties": {
              "message_id": {
                "description": "要更新的消息 ID",
                "type": "string"
              },
              "patch": {
                "allOf": [
                  {
                    "$ref": "#/definitions/MessagePacket"
                  }
                ],
                "description": "更新内容"
              }
            },
            "required": [
              "message_id",
              "patch"
            ],
            "type": "object"
          },
          "ChatUiEvent": {
            "description": "UI 事件类型",
            "oneOf": [
              {
                "description": "追加消息",
                "properties": {
                  "payload": {
                    "$ref": "#/definitions/ChatAppendPayload"
                  },
                  "type": {
                    "enum": [
                      "ChatAppend"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "payload",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "局部更新(替换某条消息)",
                "properties": {
                  "payload": {
                    "$ref": "#/definitions/ChatPatchPayload"
                  },
                  "type": {
                    "enum": [
                      "ChatPatch"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "payload",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "元信息变更(滚动、主题、清屏、状态)",
                "properties": {
                  "payload": {
                    "$ref": "#/definitions/ChatMetaPayload"
                  },
                  "type": {
                    "enum": [
                      "ChatMeta"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "payload",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "MessagePacket": {
            "description": "消息包 - Chat 系统的核心数据结构",
            "properties": {
              "hash": {
                "description": "Message hash (for deduplication and idempotency)",
                "pattern": "^[0-9a-f]{32}$",
                "title": "Hash",
                "type": "string"
              },
              "id": {
                "description": "Unique message ID",
                "title": "ID",
                "type": "string"
              },
              "meta": {
                "additionalProperties": true,
                "description": "Message metadata",
                "title": "Meta",
                "type": "object"
              },
              "msg_type": {
                "allOf": [
                  {
                    "$ref": "#/definitions/MessageType"
                  }
                ],
                "description": "Message type (text/image/file/audio, etc.)",
                "title": "Msg Type"
              },
              "payload": {
                "description": "Message content payload",
                "title": "Payload"
              },
              "protocol_version": {
                "description": "Protocol version",
                "title": "Protocol Version",
                "type": "string"
              },
              "stream_hint": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/StreamHint"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Stream shard info",
                "title": "Stream Hint"
              },
              "timestamp": {
                "description": "Message creation timestamp (Unix ms)",
                "format": "int64",
                "title": "Timestamp",
                "type": "integer"
              }
            },
            "required": [
              "hash",
              "id",
              "meta",
              "msg_type",
              "payload",
              "protocol_version",
              "timestamp"
            ],
            "type": "object"
          },
          "MessageType": {
            "description": "消息类型",
            "oneOf": [
              {
                "description": "纯文本",
                "enum": [
                  "text"
                ],
                "type": "string"
              },
              {
                "description": "图片",
                "enum": [
                  "image"
                ],
                "type": "string"
              },
              {
                "description": "文件",
                "enum": [
                  "file"
                ],
                "type": "string"
              },
              {
                "description": "音频",
                "enum": [
                  "audio"
                ],
                "type": "string"
              },
              {
                "description": "视频",
                "enum": [
                  "video"
                ],
                "type": "string"
              },
              {
                "description": "OCR 识别结果",
                "enum": [
                  "ocr_text"
                ],
                "type": "string"
              },
              {
                "description": "流式分片",
                "enum": [
                  "stream"
                ],
                "type": "string"
              },
              {
                "description": "控制消息(如清屏、状态变更)",
                "enum": [
                  "control"
                ],
                "type": "string"
              },
              {
                "description": "错误消息",
                "enum": [
                  "error"
                ],
                "type": "string"
              },
              {
                "description": "网页快照",
                "enum": [
                  "web_snapshot"
                ],
                "type": "string"
              },
              {
                "description": "系统消息",
                "enum": [
                  "system"
                ],
                "type": "string"
              }
            ]
          },
          "MetaAction": {
            "description": "元操作类型",
            "oneOf": [
              {
                "description": "清屏",
                "enum": [
                  "clear"
                ],
                "type": "string"
              },
              {
                "description": "滚动到底部",
                "enum": [
                  "scroll_to_bottom"
                ],
                "type": "string"
              },
              {
                "description": "滚动到顶部",
                "enum": [
                  "scroll_to_top"
                ],
                "type": "string"
              },
              {
                "additionalProperties": false,
                "description": "滚动到指定消息",
                "properties": {
                  "scroll_to_message": {
                    "properties": {
                      "message_id": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "message_id"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "scroll_to_message"
                ],
                "type": "object"
              },
              {
                "additionalProperties": false,
                "description": "切换主题",
                "properties": {
                  "set_theme": {
                    "properties": {
                      "theme": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "theme"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "set_theme"
                ],
                "type": "object"
              },
              {
                "description": "显示加载骨架",
                "enum": [
                  "show_skeleton"
                ],
                "type": "string"
              },
              {
                "description": "隐藏加载骨架",
                "enum": [
                  "hide_skeleton"
                ],
                "type": "string"
              },
              {
                "additionalProperties": false,
                "description": "节点状态变更",
                "properties": {
                  "status_change": {
                    "properties": {
                      "status": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "status"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "status_change"
                ],
                "type": "object"
              }
            ]
          },
          "ProcessingStats": {
            "description": "处理统计",
            "properties": {
              "duration_ms": {
                "format": "uint64",
                "minimum": 0,
                "title": "Duration MS",
                "type": "integer"
              },
              "error_count": {
                "format": "uint",
                "minimum": 0,
                "title": "Error Count",
                "type": "integer"
              },
              "skipped_count": {
                "format": "uint",
                "minimum": 0,
                "title": "Skipped Count",
                "type": "integer"
              },
              "success_count": {
                "format": "uint",
                "minimum": 0,
                "title": "Success Count",
                "type": "integer"
              },
              "total_input": {
                "format": "uint",
                "minimum": 0,
                "title": "Total Input",
                "type": "integer"
              }
            },
            "required": [
              "duration_ms",
              "error_count",
              "skipped_count",
              "success_count",
              "total_input"
            ],
            "type": "object"
          },
          "ScrollHint": {
            "description": "滚动提示",
            "oneOf": [
              {
                "description": "自动滚动到底部",
                "enum": [
                  "auto"
                ],
                "type": "string"
              },
              {
                "description": "锁定当前位置",
                "enum": [
                  "lock"
                ],
                "type": "string"
              }
            ]
          },
          "StreamHint": {
            "description": "流式分片提示",
            "properties": {
              "chunk_index": {
                "description": "分片索引(从 0 开始)",
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "group_id": {
                "description": "所属消息组 ID",
                "type": "string"
              },
              "is_final": {
                "description": "是否为最后一个分片",
                "type": "boolean"
              }
            },
            "required": [
              "chunk_index",
              "group_id",
              "is_final"
            ],
            "type": "object"
          }
        },
        "description": "ChatInputNode 输出",
        "properties": {
          "attachments_json": {
            "description": "Attachments JSON array, connectable directly to io/file_upload.files_json",
            "title": "Attachments JSON",
            "type": "string",
            "x-i18n-key": "nodes.chat.input.outputs.attachments_json",
            "x-port": true
          },
          "context": {
            "additionalProperties": true,
            "description": "AgentContext wrapper, connectable directly to agent/llm context port",
            "title": "Agent Context",
            "type": "object",
            "x-i18n-key": "nodes.chat.input.outputs.context",
            "x-port": true
          },
          "conversation_id": {
            "description": "Conversation ID (passed through to downstream nodes)",
            "title": "Conversation ID",
            "type": "string",
            "x-i18n-key": "nodes.chat.input.outputs.conversation_id",
            "x-port": true
          },
          "model_override": {
            "description": "Model override (format: credential_id::model_name)",
            "title": "Model Override",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.chat.input.outputs.model_override"
          },
          "stats": {
            "allOf": [
              {
                "$ref": "#/definitions/ProcessingStats"
              }
            ],
            "description": "Processing statistics",
            "title": "Stats",
            "x-i18n-key": "nodes.chat.input.outputs.stats"
          },
          "ui_event": {
            "anyOf": [
              {
                "$ref": "#/definitions/ChatUiEvent"
              },
              {
                "type": "null"
              }
            ],
            "description": "UI event",
            "title": "Ui Event",
            "x-i18n-key": "nodes.chat.input.outputs.ui_event"
          },
          "user_message": {
            "description": "User message text",
            "title": "User Message",
            "type": "string",
            "x-i18n-key": "nodes.chat.input.outputs.user_message",
            "x-port": true
          },
          "user_message_rich": {
            "additionalProperties": true,
            "description": "Structured user message with multimodal parts",
            "title": "User Message Rich",
            "type": "object",
            "x-i18n-key": "nodes.chat.input.outputs.user_message_rich",
            "x-port": true
          },
          "workspace_id": {
            "description": "Workspace ID (passed through to chat/memory for per-workspace isolation)",
            "title": "Workspace ID",
            "type": "string",
            "x-i18n-key": "nodes.chat.input.outputs.workspace_id",
            "x-port": true
          }
        },
        "required": [
          "attachments_json",
          "context",
          "conversation_id",
          "stats",
          "user_message",
          "user_message_rich",
          "workspace_id"
        ],
        "title": "ChatInputNodeOutput",
        "type": "object",
        "x-collapsed-visible": [
          "user_message"
        ],
        "x-field-order": [
          "context",
          "user_message",
          "user_message_rich",
          "conversation_id",
          "workspace_id",
          "stats",
          "ui_event",
          "model_override",
          "attachments_json"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.chat.input"
    },
    {
      "typeId": "tools/file_ops_hub",
      "name": "File Operations Hub",
      "category": "tools",
      "description": "File operations aggregate node: only one node needed on canvas, control Agent's available file operation capabilities via toggle switches.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "allow_delete": {
            "default": false,
            "description": "是否允许删除文件(高副作用,不可逆)",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.allow_delete"
          },
          "allow_edit": {
            "default": true,
            "description": "是否允许精确编辑文件(中副作用)",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.allow_edit"
          },
          "allow_list_directory": {
            "default": true,
            "description": "是否允许列出目录(只读)",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.allow_list_directory"
          },
          "allow_read_content": {
            "default": true,
            "description": "是否允许读取文件内容(只读)",
            "title": "Allow Read Content",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.allow_read_content"
          },
          "allow_read_info": {
            "default": true,
            "description": "是否允许获取文件元信息(只读)",
            "title": "Allow Read Info",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.allow_read_info"
          },
          "allow_search": {
            "default": true,
            "description": "是否允许搜索文件内容(只读)",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.allow_search"
          },
          "allow_write": {
            "default": true,
            "description": "是否允许写入/创建文件(中副作用)",
            "type": "boolean",
            "x-control": "switch",
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.allow_write"
          },
          "config": {
            "additionalProperties": true,
            "description": "Unified configuration object (can fill JSON text directly)",
            "title": "Config",
            "type": "object",
            "x-control": "text",
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.config",
            "x-port": true
          },
          "operation": {
            "default": "",
            "description": "操作类型",
            "type": "string",
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.operation"
          },
          "path": {
            "description": "文件或目录路径(多数操作通用)",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.path"
          },
          "sandbox_root": {
            "title": "Sandbox Root",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.file_ops_hub.inputs.sandbox_root"
          }
        },
        "required": [
          "allow_delete",
          "allow_edit",
          "allow_list_directory",
          "allow_read_content",
          "allow_read_info",
          "allow_search",
          "allow_write"
        ],
        "title": "FileOpsHubInput",
        "type": "object",
        "x-collapsed-visible": [
          "sandbox_root"
        ],
        "x-field-order": [
          "operation",
          "path",
          "sandbox_root",
          "config",
          "allow_read_info",
          "allow_read_content",
          "allow_list_directory",
          "allow_search",
          "allow_write",
          "allow_edit",
          "allow_delete"
        ]
      },
      "outputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "error": {
            "description": "错误信息(操作被禁止或执行失败)",
            "type": [
              "string",
              "null"
            ],
            "x-i18n-key": "nodes.tools.file_ops_hub.outputs.error"
          },
          "operation": {
            "description": "实际执行的操作类型",
            "type": "string",
            "x-i18n-key": "nodes.tools.file_ops_hub.outputs.operation"
          },
          "result": {
            "description": "操作结果(JSON 序列化的子工具输出)",
            "x-i18n-key": "nodes.tools.file_ops_hub.outputs.result"
          }
        },
        "required": [
          "operation",
          "result"
        ],
        "title": "FileOpsHubOutput",
        "type": "object",
        "x-collapsed-visible": [
          "operation"
        ],
        "x-field-order": [
          "operation",
          "error",
          "result"
        ]
      },
      "builtin": true,
      "i18nKeyPrefix": "nodes.tools.file_ops_hub"
    }
  ],
  "timestamp": "2026-05-10T05:29:12.183323312+00:00"
}