openapi: 3.0.3
info:
  title: FlowDrop™ API
  description: |
    FlowDrop is a visual workflow editor for AI applications and data processing pipelines.
    This API provides comprehensive endpoints for managing workflows, node types, pipeline execution, and port configuration.

    ## Features
    - **Workflow Management**: Complete CRUD operations for workflows with nodes and edges
    - **Node Type Discovery**: Browse and search available node processors with metadata
    - **Pipeline Execution**: Execute workflows with real-time status tracking and job management
    - **Port Configuration**: Dynamic port compatibility system with data type management
    - **Real-time Updates**: Track node execution status and pipeline progress
    - **Import/Export**: Import and export workflows in JSON format
    - **Validation**: Workflow validation before execution
    - **Agent Spec Integration**: Import/export Oracle Open Agent Spec flows and execute on compatible runtimes (WayFlow/PyAgentSpec)

    ## Architecture
    - **Frontend**: Svelte 5 + XYFlow for visual workflow editing
    - **Backend**: Drupal 10/11 with custom node processor plugins
    - **API**: RESTful JSON API with consistent response format
    - **Storage**: Drupal entity system with workflow versioning

    ## Authentication
    API endpoints require Drupal authentication. Use Bearer token or session-based authentication.

    ## Rate Limiting
    - Node Discovery: 100 requests/minute
    - Workflow Operations: 50 requests/minute
    - Pipeline Execution: 20 requests/minute

    ## Error Handling
    All errors return a consistent format with success flag, error message, and optional details.
  version: 1.0.0
  contact:
    name: FlowDrop Support
    email: shibinkidd@gmail.com
    url: https://www.drupal.org/project/issues/flowdrop?categories=All
servers:
  - url: http://localhost:5173/api/flowdrop
    description: Local development server (Svelte)
  - url: https://flowdrop.ddev.site/api/flowdrop
    description: Local Drupal server
security:
  - BearerAuth: []
  - SessionAuth: []
tags:
  - name: System
    description: System health and status endpoints
  - name: Node Types
    description: Node type discovery and metadata endpoints
  - name: Configuration
    description: System configuration endpoints including port configuration
  - name: Workflows
    description: Workflow CRUD operations
  - name: Pipeline
    description: Pipeline execution and monitoring
  - name: Playground
    description: Interactive workflow testing and chat interface
  - name: Interrupts
    description: |
      Human-in-the-Loop (HITL) interrupt endpoints for workflow interactions.
      Interrupts allow workflows to pause execution and request user input.
  - name: Validation
    description: Workflow validation
  - name: Import/Export
    description: Workflow import and export operations
  - name: Chat
    description: |
      LLM Chat Interface for natural language workflow building.
      Translates user intent into DSL commands via a backend LLM integration.
  - name: Agent Spec
    description: |
      Oracle Open Agent Spec integration endpoints.
      Provides bidirectional conversion between FlowDrop workflows and Agent Spec format,
      plus runtime execution on compatible runtimes (WayFlow, PyAgentSpec).
      @see https://github.com/oracle/agent-spec
paths:
  /health:
    get:
      operationId: getHealth
      summary: API health check
      description: |
        Check if the FlowDrop API is running and responsive.
        This endpoint is at the root level following industry conventions
        for Kubernetes liveness/readiness probes and load balancer health checks.
      tags:
        - System
      security: []
      responses:
        '200':
          description: API is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: healthy
                  timestamp:
                    type: string
                    format: date-time
                  version:
                    type: string
                    example: 1.0.0
                  service:
                    type: string
                    example: FlowDrop API
                  uptime:
                    type: integer
                    description: Uptime in seconds
                    example: 3600
        '404':
          $ref: '#/components/responses/NotFound'
        '503':
          description: Service unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /system/config:
    get:
      operationId: getSystemConfig
      summary: Get system configuration
      description: Retrieve public system configuration settings
      tags:
        - System
      responses:
        '200':
          description: System configuration retrieved successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiResponse'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          version:
                            type: string
                            example: 1.0.0
                          features:
                            type: object
                            additionalProperties:
                              type: boolean
                            description: Enabled features
                          limits:
                            type: object
                            properties:
                              maxWorkflowNodes:
                                type: integer
                              maxConcurrentExecutions:
                                type: integer
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /system/version:
    get:
      operationId: getSystemVersion
      summary: Get API version
      description: Retrieve the current API version information
      tags:
        - System
      security: []
      responses:
        '200':
          description: Version information retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  version:
                    type: string
                    example: 1.0.0
                  build:
                    type: string
                    example: 2026.01.26
                  api_version:
                    type: string
                    example: v1
        '404':
          $ref: '#/components/responses/NotFound'
  /nodes:
    get:
      operationId: listNodeTypes
      summary: Get all available node types
      description: |
        Retrieve all available node processors with optional filtering by category, search query, and pagination.
        Supports filtering by node category (models, data_processing, input_output, etc.) and search queries.
      tags:
        - Node Types
      parameters:
        - name: category
          in: query
          description: Filter by node category
          required: false
          schema:
            $ref: '#/components/schemas/NodeCategory'
        - name: search
          in: query
          description: Search node types by name, description, or tags
          required: false
          schema:
            type: string
            maxLength: 100
        - name: limit
          in: query
          description: Maximum number of results (1-1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
        - name: offset
          in: query
          description: Number of results to skip for pagination
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: List of node types retrieved successfully
          headers:
            X-Total-Count:
              description: Total number of nodes matching the filter
              schema:
                type: integer
            X-Page-Size:
              description: Number of nodes per page
              schema:
                type: integer
            X-Page-Offset:
              description: Current page offset
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodesResponse'
              examples:
                success:
                  value:
                    success: true
                    data:
                      - id: openai_chat_executor
                        name: OpenAI Chat
                        description: Chat completion using OpenAI's GPT models
                        category: ai
                        version: 1.0.0
                        icon: mdi:chat
                        color: '#10a37f'
                        type: default
                        supportedTypes:
                          - default
                          - simple
                        inputs:
                          - id: data
                            name: Input Data
                            type: input
                            dataType: mixed
                            required: false
                            description: Input data for the node
                        outputs:
                          - id: response
                            name: Response
                            type: output
                            dataType: string
                            description: The OpenAI response
                        configSchema:
                          type: object
                          properties:
                            model:
                              type: string
                              title: Model
                              default: gpt-4o-mini
                              enum:
                                - gpt-4o-mini
                                - gpt-5
                                - gpt-4.1
                            temperature:
                              type: number
                              title: Temperature
                              default: 0.7
                              minimum: 0
                              maximum: 2
                            maxTokens:
                              type: integer
                              title: Max Tokens
                              default: 1000
                              minimum: 1
                              maximum: 4096
                            apiKey:
                              type: string
                              title: API Key
                              format: hidden
                        tags:
                          - openai
                          - gpt
                          - chat
                          - ai
                    message: Found 1 node types
        '400':
          $ref: '#/components/responses/BadRequest'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /nodes/{id}:
    get:
      operationId: getNodeType
      summary: Get node type by ID
      description: Retrieve detailed metadata for a specific node type by its unique identifier
      tags:
        - Node Types
      parameters:
        - name: id
          in: path
          description: Node type unique identifier
          required: true
          schema:
            type: string
            example: calculator
      responses:
        '200':
          description: Node type details retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodeTypeResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /port-config:
    get:
      operationId: getPortConfig
      summary: Get port configuration
      description: |
        Retrieve the complete port configuration system including available data types,
        compatibility rules, and default settings. This configuration determines how
        nodes can be connected in workflows based on port data types.
      tags:
        - Configuration
      responses:
        '200':
          description: Port configuration retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PortConfigResponse'
              example:
                success: true
                data:
                  version: 1.0.0
                  defaultDataType: mixed
                  dataTypes:
                    - id: string
                      name: String
                      description: Text data type
                      color: '#3b82f6'
                      category: primitive
                      aliases:
                        - text
                        - str
                      enabled: true
                    - id: number
                      name: Number
                      description: Numeric data type
                      color: '#10b981'
                      category: primitive
                      enabled: true
                    - id: mixed
                      name: Mixed
                      description: Any data type
                      color: '#6b7280'
                      category: special
                      enabled: true
                  compatibilityRules:
                    - from: string
                      to: mixed
                      description: Strings can connect to mixed ports
                    - from: number
                      to: mixed
                      description: Numbers can connect to mixed ports
                    - from: mixed
                      to: string
                      description: Mixed can connect to string with conversion
                message: Port configuration loaded successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /categories:
    get:
      operationId: getCategories
      summary: Get category definitions
      description: |
        Retrieve all available category definitions including display labels,
        icons, colors, and ordering. Categories determine how nodes are organized
        in the sidebar.

        Built-in categories are always available as defaults. This endpoint allows
        overriding built-in category metadata and defining custom categories.
      tags:
        - Configuration
      responses:
        '200':
          description: Categories retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CategoriesResponse'
              example:
                success: true
                data:
                  - name: triggers
                    label: Triggers
                    icon: mdi:lightning-bolt
                    color: var(--fd-node-cyan)
                    weight: 0
                  - name: inputs
                    label: Inputs
                    icon: mdi:arrow-down-circle
                    color: var(--fd-node-emerald)
                    weight: 1
                  - name: ml
                    label: Machine Learning
                    icon: mdi:brain
                    color: var(--fd-node-purple)
                    description: Custom ML processing nodes
                    weight: 20
                message: Categories loaded successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflows:
    get:
      operationId: listWorkflows
      summary: Get all workflows
      description: |
        Retrieve all workflows with optional search filtering and pagination.
        Returns workflow metadata including nodes, edges, and execution history.
      tags:
        - Workflows
      parameters:
        - name: search
          in: query
          description: Search workflows by name or description
          required: false
          schema:
            type: string
            maxLength: 100
        - name: tags
          in: query
          description: Filter by tags (comma-separated)
          required: false
          schema:
            type: string
        - name: limit
          in: query
          description: Maximum number of workflows to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
        - name: offset
          in: query
          description: Number of workflows to skip
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
        - name: sort
          in: query
          description: Sort field
          required: false
          schema:
            type: string
            enum:
              - created_at
              - updated_at
              - name
            default: updated_at
        - name: order
          in: query
          description: Sort direction
          required: false
          schema:
            type: string
            enum:
              - asc
              - desc
            default: desc
      responses:
        '200':
          description: List of workflows retrieved successfully
          headers:
            X-Total-Count:
              description: Total number of workflows
              schema:
                type: integer
            X-Page-Size:
              description: Workflows per page
              schema:
                type: integer
            X-Page-Offset:
              description: Current page offset
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowsResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
    post:
      operationId: createWorkflow
      summary: Create a new workflow
      description: |
        Create a new workflow with the provided name, description, nodes, and edges.
        The workflow will be assigned a unique UUID and metadata will be automatically generated.
      tags:
        - Workflows
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWorkflowRequest'
            examples:
              basic:
                summary: Basic workflow creation
                value:
                  name: My First Workflow
                  description: A simple workflow for testing
                  nodes: []
                  edges: []
              withNodes:
                summary: Workflow with nodes
                value:
                  name: AI Chat Workflow
                  description: Chat workflow using OpenAI
                  nodes:
                    - id: 550e8400-e29b-41d4-a716-446655440001
                      type: text_input
                      position:
                        x: 100
                        'y': 100
                      data:
                        label: User Input
                        config:
                          placeholder: Enter your question
                        metadata:
                          id: text_input
                          name: Text Input
                          description: Text input field for user data
                          category: inputs
                          version: 1.0.0
                          inputs: []
                          outputs:
                            - id: value
                              name: Value
                              type: output
                              dataType: string
                  edges: []
                  tags:
                    - ai
                    - chat
      responses:
        '201':
          description: Workflow created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflows/{id}:
    get:
      operationId: getWorkflow
      summary: Get workflow by ID
      description: Retrieve a specific workflow with all its nodes, edges, and metadata
      tags:
        - Workflows
      parameters:
        - name: id
          in: path
          description: Workflow UUID
          required: true
          schema:
            type: string
            format: uuid
            example: 123e4567-e89b-12d3-a456-426614174000
      responses:
        '200':
          description: Workflow details retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
    put:
      operationId: updateWorkflow
      summary: Update workflow
      description: |
        Update an existing workflow. All fields are optional - only provided fields will be updated.
        The updatedAt timestamp will be automatically set to the current time.
      tags:
        - Workflows
      parameters:
        - name: id
          in: path
          description: Workflow UUID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateWorkflowRequest'
      responses:
        '200':
          description: Workflow updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalServerError'
    delete:
      operationId: deleteWorkflow
      summary: Delete workflow
      description: Permanently delete a workflow and all associated data including execution history
      tags:
        - Workflows
      parameters:
        - name: id
          in: path
          description: Workflow UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Workflow deleted successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Workflow deleted successfully
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflows/validate:
    post:
      operationId: validateWorkflow
      summary: Validate workflow
      description: |
        Validate a workflow structure without saving it. Checks for:
        - Valid node connections and port compatibility
        - Required configuration fields
        - Circular dependencies
        - Orphaned nodes
        - Missing required inputs
      tags:
        - Validation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Workflow'
      responses:
        '200':
          description: Validation results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflows/{id}/export:
    get:
      operationId: exportWorkflow
      summary: Export workflow
      description: Export a workflow as JSON or YAML format
      tags:
        - Import/Export
      parameters:
        - name: id
          in: path
          description: Workflow UUID
          required: true
          schema:
            type: string
            format: uuid
        - name: format
          in: query
          description: Export format
          required: false
          schema:
            type: string
            enum:
              - json
              - yaml
            default: json
      responses:
        '200':
          description: Workflow exported successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workflow'
            application/x-yaml:
              schema:
                type: string
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflows/import:
    post:
      operationId: importWorkflow
      summary: Import workflow
      description: Import a workflow from JSON format. A new UUID will be assigned to the imported workflow.
      tags:
        - Import/Export
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Workflow'
      responses:
        '201':
          description: Workflow imported successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflows/{id}/execute:
    post:
      operationId: executeWorkflow
      summary: Execute workflow
      description: |
        Create a new pipeline and start execution in one call.
        This is a convenience endpoint that combines pipeline creation with immediate execution.
        Returns the pipeline ID and initial status for tracking.
      tags:
        - Pipeline
      parameters:
        - name: id
          in: path
          description: Workflow UUID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                inputs:
                  type: object
                  description: Input values for specific nodes
                  additionalProperties: true
                options:
                  type: object
                  properties:
                    timeout:
                      type: integer
                      description: Execution timeout in milliseconds
                    maxSteps:
                      type: integer
                      description: Maximum number of execution steps
      responses:
        '202':
          description: Workflow execution started
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiResponse'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          execution_id:
                            type: string
                            format: uuid
                            description: Pipeline/execution ID for tracking
                          status:
                            type: string
                            enum:
                              - pending
                              - running
                          started_at:
                            type: string
                            format: date-time
                          estimated_completion:
                            type: string
                            format: date-time
                            description: Estimated completion time (if available)
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /executions:
    get:
      operationId: listExecutions
      summary: List execution history
      description: |
        Retrieve execution history across all workflows.
        Supports filtering by workflow, status, and date range.
      tags:
        - Pipeline
      parameters:
        - name: workflow_id
          in: query
          description: Filter by workflow UUID
          required: false
          schema:
            type: string
            format: uuid
        - name: status
          in: query
          description: Filter by execution status
          required: false
          schema:
            type: string
            enum:
              - pending
              - running
              - completed
              - failed
              - cancelled
        - name: limit
          in: query
          description: Maximum number of results
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
        - name: offset
          in: query
          description: Number of results to skip
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: Execution history retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PipelineListResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /executions/{id}:
    get:
      operationId: getExecution
      summary: Get execution status
      description: |
        Retrieve the current status and details of a specific execution.
        This is an alias for the pipeline detail endpoint.
      tags:
        - Pipeline
      parameters:
        - name: id
          in: path
          description: Execution/Pipeline UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Execution status retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PipelineDetailResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /executions/{id}/cancel:
    post:
      operationId: cancelExecution
      summary: Cancel execution
      description: |
        Cancel a running execution. Only executions in 'pending' or 'running'
        status can be cancelled.
      tags:
        - Pipeline
      parameters:
        - name: id
          in: path
          description: Execution/Pipeline UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Execution cancelled successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Execution cancelled successfully
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Execution cannot be cancelled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /executions/{id}/logs:
    get:
      operationId: getExecutionLogs
      summary: Get execution logs
      description: Retrieve detailed execution logs for a specific execution
      tags:
        - Pipeline
      parameters:
        - name: id
          in: path
          description: Execution/Pipeline UUID
          required: true
          schema:
            type: string
            format: uuid
        - name: level
          in: query
          description: Filter by log level
          required: false
          schema:
            type: string
            enum:
              - debug
              - info
              - warning
              - error
        - name: node_id
          in: query
          description: Filter by node ID
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Execution logs retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/LogEntry'
                  message:
                    type: string
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflow/{workflow_id}/pipelines:
    get:
      operationId: listWorkflowPipelines
      summary: List workflow pipelines
      description: Get all pipeline executions for a specific workflow
      tags:
        - Pipeline
      parameters:
        - name: workflow_id
          in: path
          description: Workflow ID or machine name
          required: true
          schema:
            type: string
        - name: status
          in: query
          description: Filter by pipeline status
          required: false
          schema:
            type: string
            enum:
              - pending
              - running
              - completed
              - failed
              - cancelled
      responses:
        '200':
          description: List of pipeline executions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PipelineListResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /pipeline/{id}:
    get:
      operationId: getPipeline
      summary: Get pipeline execution details
      description: |
        Retrieve detailed information about a pipeline execution including:
        - Overall pipeline status
        - Individual job statuses for each node
        - Node execution information (execution count, duration, errors)
        - Job status summary
      tags:
        - Pipeline
      parameters:
        - name: id
          in: path
          description: Pipeline UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Pipeline details retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PipelineDetailResponse'
              example:
                status: running
                jobs:
                  - id: job-1
                    node_id: node-1
                    status: completed
                    execution_count: 5
                    started: '2024-01-20T10:00:00Z'
                    completed: '2024-01-20T10:00:05Z'
                    execution_time: 5000
                  - id: job-2
                    node_id: node-2
                    status: running
                    execution_count: 3
                    started: '2024-01-20T10:00:05Z'
                node_statuses:
                  node-1:
                    status: completed
                    last_executed: '2024-01-20T10:00:05Z'
                    execution_time: 5000
                  node-2:
                    status: running
                    last_executed: '2024-01-20T10:00:05Z'
                job_status_summary:
                  total: 5
                  pending: 0
                  running: 1
                  completed: 3
                  failed: 1
                  cancelled: 0
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /pipeline/{id}/status:
    get:
      operationId: getPipelineStatus
      summary: Get pipeline status
      description: |
        Retrieve only the current status of a pipeline (lightweight endpoint).
        Use this for polling when you only need the status, not full details.
      tags:
        - Pipeline
      parameters:
        - name: id
          in: path
          description: Pipeline UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Pipeline status retrieved successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiResponse'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          id:
                            type: string
                            format: uuid
                          status:
                            type: string
                            enum:
                              - pending
                              - running
                              - completed
                              - failed
                              - cancelled
                          progress:
                            type: number
                            minimum: 0
                            maximum: 100
                            description: Completion percentage (0-100)
                          updated:
                            type: string
                            format: date-time
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /pipeline/{id}/execute:
    post:
      operationId: executePipeline
      summary: Execute pipeline
      description: Start execution of a pipeline
      tags:
        - Pipeline
      parameters:
        - name: id
          in: path
          description: Pipeline UUID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                inputs:
                  type: object
                  description: Input values for specific nodes
                  additionalProperties: true
                options:
                  type: object
                  properties:
                    timeout:
                      type: integer
                      description: Execution timeout in seconds
                    maxSteps:
                      type: integer
                      description: Maximum number of execution steps
      responses:
        '202':
          description: Pipeline execution started
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PipelineExecutionResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /pipeline/{id}/stop:
    post:
      operationId: stopPipeline
      summary: Stop pipeline execution
      description: Cancel a running pipeline execution
      tags:
        - Pipeline
      parameters:
        - name: id
          in: path
          description: Pipeline UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Pipeline stopped successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Pipeline cannot be stopped
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /pipeline/{id}/logs:
    get:
      operationId: getPipelineLogs
      summary: Get pipeline execution logs
      description: Retrieve detailed execution logs for a pipeline
      tags:
        - Pipeline
      parameters:
        - name: id
          in: path
          description: Pipeline UUID
          required: true
          schema:
            type: string
            format: uuid
        - name: level
          in: query
          description: Filter by log level
          required: false
          schema:
            type: string
            enum:
              - debug
              - info
              - warning
              - error
      responses:
        '200':
          description: Pipeline logs retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/LogEntry'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflows/{id}/playground/sessions:
    get:
      operationId: listPlaygroundSessions
      summary: List playground sessions for a workflow
      description: |
        Retrieve all playground sessions associated with a workflow.
        Sessions are used to test and interact with workflows in an isolated environment.
      tags:
        - Playground
      parameters:
        - name: id
          in: path
          description: Workflow UUID
          required: true
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          description: Maximum number of sessions to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: offset
          in: query
          description: Number of sessions to skip
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: List of playground sessions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlaygroundSessionsResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
    post:
      operationId: createPlaygroundSession
      summary: Create a new playground session
      description: |
        Create a new playground session for testing a workflow.
        The session can be named for easy identification.
      tags:
        - Playground
      parameters:
        - name: id
          in: path
          description: Workflow UUID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Optional session name
                  maxLength: 100
                  example: Test Session 1
                metadata:
                  type: object
                  description: Optional metadata for the session
                  additionalProperties: true
      responses:
        '201':
          description: Session created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlaygroundSessionResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /playground/sessions/{sessionId}:
    get:
      operationId: getPlaygroundSession
      summary: Get playground session details
      description: |
        Retrieve detailed information about a specific playground session,
        including its current status and configuration.
      tags:
        - Playground
      parameters:
        - name: sessionId
          in: path
          description: Playground session UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Session details retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlaygroundSessionResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
    delete:
      operationId: deletePlaygroundSession
      summary: Delete a playground session
      description: |
        Permanently delete a playground session and all its messages.
        This action cannot be undone.
      tags:
        - Playground
      parameters:
        - name: sessionId
          in: path
          description: Playground session UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Session deleted successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Session deleted successfully
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /playground/sessions/{sessionId}/messages:
    get:
      operationId: listPlaygroundMessages
      summary: Get messages from a playground session
      description: |
        Retrieve messages from a playground session with optional filtering.
        Supports polling via the `since` parameter to fetch only new messages.
      tags:
        - Playground
      parameters:
        - name: sessionId
          in: path
          description: Playground session UUID
          required: true
          schema:
            type: string
            format: uuid
        - name: since
          in: query
          description: |
            Sequence number cursor — returns only messages with sequenceNumber
            greater than this value (forward pagination). Used for efficient
            polling of the live conversation tail. Mutually exclusive with `before`.
          required: false
          schema:
            type: integer
            minimum: 0
        - name: before
          in: query
          description: |
            Sequence number cursor for backward pagination — returns the page of
            messages with sequenceNumber LESS than this value, selecting the
            `limit` messages with the highest sequence numbers below the cursor
            (i.e. the page immediately older than the cursor). Used for
            "load older" on scroll-up. Mutually exclusive with `since`.
          required: false
          schema:
            type: integer
            minimum: 0
        - name: latest
          in: query
          description: |
            When true, return the most recent `limit` messages (the conversation
            tail), ignoring `since` and `before`. Use for the initial load of a
            chat surface. Defaults to false, which preserves the legacy
            oldest-first behavior when no cursor is supplied.
          required: false
          schema:
            type: boolean
            default: false
        - name: limit
          in: query
          description: Maximum number of messages to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
            default: 100
      responses:
        '200':
          description: Messages retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlaygroundMessagesResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
    post:
      operationId: sendPlaygroundMessage
      summary: Send a message to the playground session
      description: |
        Send a user message or trigger workflow execution with inputs.
        This starts or continues the conversation in the playground.

        The message is created with status "pending" and processing begins immediately
        (synchronously) or is queued (asynchronously) based on the session's execution mode.
        The response returns immediately with the message entity, allowing clients to
        poll the message status endpoint to track processing progress.

        Messages are processed in sequence order within a session to ensure proper
        conversation flow. If a previous message is not yet complete, the request
        will be rejected with a conflict error.
      tags:
        - Playground
      parameters:
        - name: sessionId
          in: path
          description: Playground session UUID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlaygroundMessageRequest'
            examples:
              chatMessage:
                summary: Simple chat message
                value:
                  content: Hello, can you help me analyze this data?
              withInputs:
                summary: Message with additional inputs
                value:
                  content: Process this file
                  inputs:
                    file_path: /data/input.csv
                    options:
                      format: csv
                      headers: true
      responses:
        '200':
          description: Message sent and workflow execution started
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlaygroundMessageResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Session is already executing
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /playground/sessions/{sessionId}/messages/{messageId}:
    get:
      operationId: getPlaygroundMessage
      summary: Get a single message
      description: |
        Retrieve a specific message from a playground session by its ID.
        Returns full message details including status and metadata.
      tags:
        - Playground
      parameters:
        - name: sessionId
          in: path
          description: Playground session UUID
          required: true
          schema:
            type: string
            format: uuid
        - name: messageId
          in: path
          description: Message UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Message retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlaygroundMessageResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /playground/sessions/{sessionId}/messages/{messageId}/status:
    get:
      operationId: getPlaygroundMessageStatus
      summary: Get message status
      description: |
        Retrieve only the status of a message (lightweight endpoint for polling).
        Useful for checking if message processing is complete without fetching full message data.
      tags:
        - Playground
      parameters:
        - name: sessionId
          in: path
          description: Playground session UUID
          required: true
          schema:
            type: string
            format: uuid
        - name: messageId
          in: path
          description: Message UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Message status retrieved successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiResponse'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          id:
                            type: string
                            format: uuid
                            description: Message unique identifier
                          status:
                            $ref: '#/components/schemas/PlaygroundMessageStatus'
                          sequenceNumber:
                            type: integer
                            description: Message sequence number
                          timestamp:
                            type: string
                            format: date-time
                            description: Message timestamp
                        required:
                          - id
                          - status
                          - sequenceNumber
                          - timestamp
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /playground/sessions/{sessionId}/stop:
    post:
      operationId: stopPlaygroundExecution
      summary: Stop playground execution
      description: |
        Stop the currently running execution in the playground session.
        This cancels any pending workflow operations.
      tags:
        - Playground
      parameters:
        - name: sessionId
          in: path
          description: Playground session UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Execution stopped successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Execution stopped
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: No execution is running
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflows/{id}/chat/messages:
    post:
      operationId: sendChatMessage
      summary: Send a chat message
      description: |
        Send a natural language message to the LLM chat backend for a specific workflow.
        The request includes the current workflow state and optional conversation history
        so the LLM can generate contextually relevant responses.

        The LLM response may contain plain text explanations and/or DSL commands
        in ```flowdrop fenced code blocks. The frontend extracts and previews
        these commands before execution.
      tags:
        - Chat
      parameters:
        - name: id
          in: path
          description: Workflow ID
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChatRequest'
            examples:
              simpleMessage:
                summary: Simple chat message
                value:
                  message: Add a processing node called "transform"
                  workflowState:
                    nodes: []
                    edges: []
              withHistory:
                summary: Message with conversation history
                value:
                  message: Now connect it to the start node
                  workflowState:
                    nodes:
                      - id: node-1
                        type: start
                      - id: node-2
                        type: processing
                    edges: []
                  history:
                    - role: user
                      content: Add a processing node called "transform"
                    - role: assistant
                      content: Done! I've added a processing node named "transform".
      responses:
        '200':
          description: Chat response with LLM-generated content
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatMessagesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
    get:
      operationId: getChatHistory
      summary: Get chat conversation history
      description: |
        Retrieve the conversation history for a workflow's chat session.
        Returns an array of messages with role (user/assistant) and content.
      tags:
        - Chat
      parameters:
        - name: id
          in: path
          description: Workflow ID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Conversation history retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatHistoryResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
    delete:
      operationId: clearChatHistory
      summary: Clear chat conversation history
      description: |
        Clear the conversation history for a workflow's chat session.
        This resets the chat context, starting a fresh conversation.
      tags:
        - Chat
      parameters:
        - name: id
          in: path
          description: Workflow ID
          required: true
          schema:
            type: string
      responses:
        '204':
          description: Conversation history cleared successfully
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /interrupts/{interruptId}:
    get:
      operationId: getInterrupt
      summary: Get interrupt details
      description: |
        Retrieve details about a specific interrupt request.
        Interrupts are created when a workflow execution requires human input.
      tags:
        - Interrupts
      parameters:
        - name: interruptId
          in: path
          description: Interrupt UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Interrupt details retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InterruptResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
    post:
      operationId: resolveInterrupt
      summary: Resolve interrupt
      description: |
        Submit user response to resolve a pending interrupt.
        The value type depends on the interrupt type:
        - confirmation: boolean (true = confirmed)
        - choice: string or string[] (selected values)
        - text: string (user input)
        - form: object (form data matching schema)
      tags:
        - Interrupts
      parameters:
        - name: interruptId
          in: path
          description: Interrupt UUID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InterruptResolveRequest'
            examples:
              confirmation:
                summary: Confirmation response
                value:
                  value: true
              choice:
                summary: Choice selection
                value:
                  value: option1
              multipleChoice:
                summary: Multiple choice selection
                value:
                  value:
                    - option1
                    - option3
              text:
                summary: Text input
                value:
                  value: User provided text response
              form:
                summary: Form data
                value:
                  value:
                    name: John Doe
                    email: john@example.com
                    priority: high
      responses:
        '200':
          description: Interrupt resolved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InterruptResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Interrupt already resolved or cancelled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /interrupts/{interruptId}/cancel:
    post:
      operationId: cancelInterrupt
      summary: Cancel interrupt
      description: |
        Cancel a pending interrupt without providing a response.
        This may not be allowed for all interrupts - check the allowCancel
        property in the interrupt data before attempting to cancel.
      tags:
        - Interrupts
      parameters:
        - name: interruptId
          in: path
          description: Interrupt UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Interrupt cancelled successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Interrupt cancelled
        '400':
          description: Interrupt cannot be cancelled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Interrupt already resolved or cancelled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /playground/sessions/{sessionId}/interrupts:
    get:
      operationId: listSessionInterrupts
      summary: List session interrupts
      description: |
        List all interrupts associated with a playground session.
        Useful for displaying pending interrupts or reviewing interrupt history.
      tags:
        - Interrupts
      parameters:
        - name: sessionId
          in: path
          description: Playground session UUID
          required: true
          schema:
            type: string
            format: uuid
        - name: status
          in: query
          description: Filter by interrupt status
          required: false
          schema:
            type: string
            enum:
              - pending
              - resolved
              - cancelled
        - name: limit
          in: query
          description: Maximum number of interrupts to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
        - name: offset
          in: query
          description: Number of interrupts to skip
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: List of interrupts retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InterruptListResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /pipelines/{pipelineId}/interrupts:
    get:
      operationId: listPipelineInterrupts
      summary: List pipeline interrupts
      description: |
        List all interrupts associated with a pipeline execution.
        Useful for monitoring workflow progress and pending user actions.
      tags:
        - Interrupts
      parameters:
        - name: pipelineId
          in: path
          description: Pipeline UUID
          required: true
          schema:
            type: string
            format: uuid
        - name: status
          in: query
          description: Filter by interrupt status
          required: false
          schema:
            type: string
            enum:
              - pending
              - resolved
              - cancelled
        - name: limit
          in: query
          description: Maximum number of interrupts to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
        - name: offset
          in: query
          description: Number of interrupts to skip
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: List of interrupts retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InterruptListResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /agentspec/flows/execute:
    post:
      operationId: agentSpecExecuteFlow
      summary: Execute an Agent Spec flow
      description: |
        Submit an Agent Spec flow for execution on the configured runtime
        (WayFlow, PyAgentSpec, or other compatible runtimes).

        The flow is posted as Agent Spec JSON. The runtime returns an
        execution ID for tracking progress via polling or WebSocket.
      tags:
        - Agent Spec
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentSpecExecutionRequest'
      responses:
        '200':
          description: Flow execution started successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSpecExecutionResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /agentspec/executions/{id}:
    get:
      operationId: agentSpecGetExecutionStatus
      summary: Get Agent Spec execution status
      description: |
        Retrieve the current status and per-node execution info
        for a running or completed Agent Spec execution.
      tags:
        - Agent Spec
      parameters:
        - name: id
          in: path
          description: Execution ID from the runtime
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Execution status retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSpecExecutionStatus'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /agentspec/executions/{id}/cancel:
    post:
      operationId: agentSpecCancelExecution
      summary: Cancel Agent Spec execution
      description: |
        Cancel a running Agent Spec execution. Only executions in
        'running' status can be cancelled.
      tags:
        - Agent Spec
      parameters:
        - name: id
          in: path
          description: Execution ID from the runtime
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Execution cancelled successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Execution cancelled successfully
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Execution cannot be cancelled (already completed or failed)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /agentspec/executions/{id}/results:
    get:
      operationId: agentSpecGetExecutionResults
      summary: Get Agent Spec execution results
      description: |
        Retrieve the final results of a completed Agent Spec execution.
        Returns null/404 if the execution is still running or was cancelled.
      tags:
        - Agent Spec
      parameters:
        - name: id
          in: path
          description: Execution ID from the runtime
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Execution results retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSpecExecutionResults'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /agentspec/executions/{id}/stream:
    get:
      operationId: agentSpecStreamExecution
      summary: Stream Agent Spec execution updates (WebSocket)
      description: |
        WebSocket endpoint for real-time execution updates.
        Streams per-node status changes and execution events as they occur.

        **Protocol**: WebSocket (upgrade from HTTP)

        **Messages sent by server**:
        - `{"type": "node_status", "node": "<name>", "status": {...}}`
        - `{"type": "execution_complete", "results": {...}}`
        - `{"type": "execution_error", "error": "<message>"}`
      tags:
        - Agent Spec
      parameters:
        - name: id
          in: path
          description: Execution ID from the runtime
          required: true
          schema:
            type: string
      responses:
        '101':
          description: WebSocket upgrade successful
        '200':
          description: WebSocket connection established (upgrade to ws://)
        '404':
          $ref: '#/components/responses/NotFound'
  /agentspec/flows/validate:
    post:
      operationId: agentSpecValidateFlow
      summary: Validate Agent Spec flow on runtime
      description: |
        Validate an Agent Spec flow specification against the runtime
        without executing it. Checks for structural correctness,
        valid node references, and property compatibility.
      tags:
        - Agent Spec
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentSpecFlow'
      responses:
        '200':
          description: Validation result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSpecRuntimeValidation'
        '400':
          $ref: '#/components/responses/BadRequest'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /agentspec/agents:
    get:
      operationId: agentSpecListAgents
      summary: List available agents on the runtime
      description: |
        Retrieve a list of agents registered on the Agent Spec runtime.
        These agents can be referenced by `agent_node` components.
      tags:
        - Agent Spec
      responses:
        '200':
          description: List of available agents
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AgentSpecRuntimeAgent'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /agentspec/tools:
    get:
      operationId: agentSpecListTools
      summary: List available tools on the runtime
      description: |
        Retrieve a list of tools registered on the Agent Spec runtime.
        These tools can be referenced by `tool_node` components.
      tags:
        - Agent Spec
      responses:
        '200':
          description: List of available tools
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AgentSpecRuntimeTool'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /agentspec/health:
    get:
      operationId: agentSpecHealthCheck
      summary: Check Agent Spec runtime health
      description: |
        Verify that the configured Agent Spec runtime is available
        and responding. Used to check connectivity before execution.
      tags:
        - Agent Spec
      security: []
      responses:
        '200':
          description: Runtime is healthy
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSpecRuntimeHealth'
        '404':
          $ref: '#/components/responses/NotFound'
        '503':
          description: Runtime unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /workflows/{id}/export/agentspec:
    get:
      operationId: exportWorkflowAsAgentSpec
      summary: Export workflow as Agent Spec JSON
      description: |
        Convert a FlowDrop workflow to Agent Spec format and return it.

        The conversion:
        - Maps FlowDrop node types to Agent Spec component types
        - Splits unified edges into control_flow_connections and data_flow_connections
        - Stores FlowDrop-specific data (positions, dynamic ports) in metadata extensions
        - Validates the workflow for Agent Spec compatibility before export
      tags:
        - Agent Spec
        - Import/Export
      parameters:
        - name: id
          in: path
          description: Workflow UUID
          required: true
          schema:
            type: string
            format: uuid
        - name: format
          in: query
          description: Output format (document wraps flow with agent/tools/LLM config)
          required: false
          schema:
            type: string
            enum:
              - flow
              - document
            default: flow
      responses:
        '200':
          description: Agent Spec JSON exported successfully
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/AgentSpecFlow'
                  - $ref: '#/components/schemas/AgentSpecDocument'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          description: Workflow cannot be exported as Agent Spec
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSpecValidationResult'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflows/import/agentspec:
    post:
      operationId: importWorkflowFromAgentSpec
      summary: Import workflow from Agent Spec JSON
      description: |
        Convert an Agent Spec flow or document to a FlowDrop workflow.

        The conversion:
        - Maps Agent Spec component types to FlowDrop node types
        - Merges control_flow_connections and data_flow_connections into unified edges
        - Auto-layouts nodes if no position metadata is present
        - Preserves Agent Spec component_type in FlowDrop extensions
      tags:
        - Agent Spec
        - Import/Export
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/AgentSpecFlow'
                - $ref: '#/components/schemas/AgentSpecDocument'
      responses:
        '200':
          description: Workflow imported successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '422':
          description: Invalid Agent Spec format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSpecValidationResult'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /workflows/{id}/validate/agentspec:
    get:
      operationId: validateWorkflowForAgentSpec
      summary: Validate workflow for Agent Spec export
      description: |
        Check if a FlowDrop workflow can be exported as Agent Spec.
        Returns validation errors and warnings without performing the export.

        Checks include:
        - Exactly one start node (terminal/trigger type)
        - At least one end node (terminal/output type)
        - Gateway nodes have branches defined
        - All nodes are reachable from start
      tags:
        - Agent Spec
        - Validation
      parameters:
        - name: id
          in: path
          description: Workflow UUID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Validation result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSpecValidationResult'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token for authentication
    SessionAuth:
      type: apiKey
      in: cookie
      name: SESS
      description: Drupal session cookie
  schemas:
    NodeCategory:
      type: string
      description: |
        Node category for organizing nodes in the sidebar.

        Any string value is accepted, allowing custom categories.
        Custom categories can be defined via the `/categories` endpoint
        with display labels, icons, and colors.

        Built-in categories with dedicated icons and colors:
        triggers, inputs, outputs, prompts, models, processing,
        logic, data, tools, helpers, vector stores, embeddings,
        memories, agents, ai, interrupts, bundles
      example: processing
    NodeDataType:
      type: string
      description: |
        Data type for node ports. The available data types are configured
        dynamically through the port configuration system.
      example: mixed
    NodeType:
      type: string
      enum:
        - note
        - simple
        - square
        - atom
        - tool
        - gateway
        - terminal
        - idea
        - default
      description: |
        Visual rendering type for the node.

        Built-in types:
        - `note` - Sticky note with markdown support
        - `simple` - Compact layout with header and description
        - `square` - Minimal square node with centered icon
        - `atom` - Minimal label-only pill/rectangle for value/transform nodes (uses extensions.ui.atom)
        - `tool` - Specialized node for agent tools
        - `gateway` - Branching control flow with dynamic branches (uses config.branches)
        - `terminal` - Circular node for workflow start/end/exit points
        - `idea` - Conceptual idea node for BPMN-like flow diagrams
        - `default` - Full-featured workflow node with dynamic port support

        ## Dynamic Port Support

        The `default` and `gateway` node types support dynamic ports:

        - **default**: Supports `config.dynamicInputs` and `config.dynamicOutputs`
          for user-defined input/output handles
        - **gateway**: Supports `config.branches` for conditional branching paths

        ## UI Extensions

        All node types support `extensions.ui.hideUnconnectedHandles` to control
        visibility of unconnected ports.
    NodeExecutionStatus:
      type: string
      enum:
        - idle
        - pending
        - running
        - completed
        - failed
        - cancelled
        - skipped
        - paused
        - interrupted
      description: Current execution status of a node
    Position:
      type: object
      properties:
        x:
          type: number
          description: X coordinate
          example: 100
        'y':
          type: number
          description: Y coordinate
          example: 200
      required:
        - x
        - 'y'
    ApiResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Whether the request was successful
        data:
          description: Response data (type varies by endpoint)
        message:
          type: string
          description: Response message
        error:
          type: string
          description: Error message (if any)
    ErrorResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            success:
              type: boolean
              example: false
            error:
              type: string
              description: Error message
            code:
              type: string
              description: Error code
            details:
              type: object
              description: Additional error details
    CategoryDefinition:
      type: object
      description: |
        Category definition with metadata for display and organization.
        Returned by the `/categories` endpoint.
      properties:
        name:
          type: string
          description: Machine name / unique identifier
          example: ml
        label:
          type: string
          description: Display label shown in UI
          example: Machine Learning
        icon:
          type: string
          description: Icon identifier (Iconify format)
          example: mdi:brain
        color:
          type: string
          description: Color token or CSS value
          example: var(--fd-node-purple)
        description:
          type: string
          description: Category description
          example: Machine learning and AI model nodes
        weight:
          type: number
          description: Sort weight for ordering (lower = earlier)
          example: 20
      required:
        - name
        - label
    PortDataTypeConfig:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the data type
          example: string
        name:
          type: string
          description: Display name for the data type
          example: String
        description:
          type: string
          description: Description of the data type
          example: Text data type
        color:
          type: string
          description: Color for the data type (CSS color value)
          example: '#3b82f6'
        category:
          type: string
          description: Category grouping for the data type
          example: primitive
        aliases:
          type: array
          items:
            type: string
          description: Alternative names for this data type
          example:
            - text
            - str
        enabled:
          type: boolean
          default: true
          description: Whether this data type is enabled
      required:
        - id
        - name
        - color
    PortCompatibilityRule:
      type: object
      properties:
        from:
          type: string
          description: Source data type ID (what you're connecting FROM)
          example: string
        to:
          type: string
          description: Target data type ID (what you're connecting TO)
          example: mixed
        description:
          type: string
          description: Optional description of why this connection is allowed
          example: Strings can connect to mixed ports
      required:
        - from
        - to
    PortConfig:
      type: object
      properties:
        version:
          type: string
          description: Version of the port configuration
          example: 1.0.0
        defaultDataType:
          type: string
          description: Default data type to use when none specified
          example: mixed
        dataTypes:
          type: array
          items:
            $ref: '#/components/schemas/PortDataTypeConfig'
          description: Available data types
        compatibilityRules:
          type: array
          items:
            $ref: '#/components/schemas/PortCompatibilityRule'
          description: Compatibility rules between data types
      required:
        - dataTypes
        - defaultDataType
    OneOfItem:
      type: object
      description: |
        JSON Schema oneOf item for labeled options.
        This is the standard JSON Schema way to define labeled select options.

        Example:
        ```json
        {
          "type": "string",
          "oneOf": [
            { "const": "draft", "title": "Draft" },
            { "const": "published", "title": "Published" }
          ]
        }
        ```
      properties:
        const:
          oneOf:
            - type: string
            - type: number
            - type: boolean
          description: The constant value for this option (JSON Schema `const` keyword)
        title:
          type: string
          description: Human-readable label for this option
        description:
          type: string
          description: Optional description for this option
      required:
        - const
    ConfigProperty:
      type: object
      description: |
        JSON Schema property definition for node configuration.
        Follows JSON Schema draft-07 specification with FlowDrop extensions for UI rendering.

        For select/dropdown fields, use standard JSON Schema patterns:
        - `enum` for simple value lists (no labels)
        - `oneOf` with `const`/`title` for labeled options
      properties:
        type:
          type: string
          enum:
            - string
            - number
            - boolean
            - array
            - object
            - integer
          description: JSON Schema type
        title:
          type: string
          description: Display title for the property
        description:
          type: string
          description: Property description
        default:
          description: Default value for the property
        enum:
          type: array
          items: {}
          description: |
            Allowed values for enum properties (simple values without labels).
            For labeled options, use `oneOf` with `const`/`title` instead.
        oneOf:
          type: array
          items:
            $ref: '#/components/schemas/OneOfItem'
          description: |
            JSON Schema oneOf for labeled options (standard approach).
            Each item should have `const` (value) and optionally `title` (label).

            Example:
            ```json
            "oneOf": [
              { "const": "draft", "title": "Draft" },
              { "const": "published", "title": "Published" }
            ]
            ```
        multiple:
          type: boolean
          description: For enum/oneOf fields, allows multiple selection (renders as checkbox group)
        minimum:
          type: number
          description: Minimum value for numeric properties
        maximum:
          type: number
          description: Maximum value for numeric properties
        step:
          type: number
          description: Step increment for number/range inputs
        minLength:
          type: integer
          description: Minimum length for string properties
        maxLength:
          type: integer
          description: Maximum length for string properties
        pattern:
          type: string
          description: Regex pattern for string validation
        placeholder:
          type: string
          description: Placeholder text for input fields
        format:
          type: string
          description: |
            Special format hints for UI rendering:

            - `multiline`: Renders as textarea
            - `hidden`: Field is hidden from UI but included in form submission
            - `range`: Renders as range slider for numeric values
            - `json`: Renders as CodeMirror JSON editor
            - `code`: Alias for json, renders as CodeMirror editor
            - `markdown`: Renders as SimpleMDE Markdown editor
            - `template`: Template editor with variable autocomplete (see below)
            - `autocomplete`: Text input with callback URL suggestions
            - `email`, `uri`, `date`, `date-time`: Standard JSON Schema formats

            ## Template Format Details

            The `template` format renders a CodeMirror editor with:

            **Syntax highlighting** for Twig/Liquid-style `{{ variable }}` placeholders

            **Inline autocomplete** triggered by:
            - Typing `{{` - Shows available variables
            - Typing `.` after an object - Shows nested properties
            - Typing `[` after an array - Shows index suggestions

            **Variable patterns supported:**
            - `{{ user }}` - Simple variable
            - `{{ user.name }}` - Nested property access
            - `{{ user.address.city }}` - Deep nesting
            - `{{ items[0] }}` - Array index access
            - `{{ orders[0].product.name }}` - Combined patterns

            **Autocomplete source:**
            Variables are derived from connected upstream nodes that have output
            schemas defined. Use the `variables` property to configure which
            input ports provide variables.
          enum:
            - multiline
            - hidden
            - range
            - json
            - code
            - markdown
            - template
            - autocomplete
            - email
            - uri
            - date
            - date-time
        variables:
          $ref: '#/components/schemas/TemplateVariablesConfig'
          description: |
            Configuration for template variable autocomplete.
            Only applicable when `format: "template"`.
            See TemplateVariablesConfig for full documentation.
        x-display-order:
          type: integer
          description: |
            Controls the display order of fields in the configuration form.
            Fields are sorted by this value in ascending order (lower values appear first).

            Use negative values to ensure fields appear at the top:
            - `-2` for `instanceTitle` (appears first)
            - `-1` for `instanceDescription` (appears second)
            - `0` or positive values for regular fields

            Fields without `x-display-order` are sorted after fields with explicit ordering.
          example: -2
        items:
          $ref: '#/components/schemas/ConfigProperty'
          description: Schema for array items
        minItems:
          type: integer
          description: Minimum number of items for array fields
        maxItems:
          type: integer
          description: Maximum number of items for array fields
        properties:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ConfigProperty'
          description: Property schemas for object fields
        autocomplete:
          $ref: '#/components/schemas/AutocompleteConfig'
          description: Configuration for autocomplete fields (when format is "autocomplete")
        readOnly:
          type: boolean
          description: |
            JSON Schema `readOnly` keyword. When true, the field is displayed but
            cannot be edited (rendered in a disabled state).
        height:
          type: string
          description: |
            Editor height as a CSS value (e.g. `200px`).
            Applies to editor fields: `json`/`code`, `markdown`, and `template`.
            Defaults: `200px` (code), `300px` (markdown), `250px` (template).
          example: 300px
        darkTheme:
          type: boolean
          description: |
            Force the editor's dark theme on or off.
            Applies to `json`/`code` and `template` fields.
            When omitted, the editor follows the resolved app theme.
        autoFormat:
          type: boolean
          default: true
          description: |
            Whether to auto-format JSON on blur.
            Applies to `json`/`code` editor fields.
        showToolbar:
          type: boolean
          default: true
          description: |
            Whether to show the editor toolbar.
            Applies to `markdown` editor fields.
        showStatusBar:
          type: boolean
          default: true
          description: |
            Whether to show the editor status bar.
            Applies to `markdown` editor fields.
        spellChecker:
          type: boolean
          default: false
          description: |
            Whether to enable spell checking.
            Applies to `markdown` editor fields.
        placeholderExample:
          type: string
          description: |
            Example template string shown as a placeholder hint.
            Applies to `template` fields.
          example: 'Hello {{ name }}, your order #{{ order_id }} is ready!'
      required:
        - type
    AutocompleteConfig:
      type: object
      description: |
        Configuration for autocomplete fields that fetch suggestions from a callback URL.
        Used when format is "autocomplete".
      properties:
        url:
          type: string
          description: |
            The callback URL to fetch autocomplete suggestions from.
            Can be relative (resolved against API base URL) or absolute.
          example: /api/users/search
        queryParam:
          type: string
          default: q
          description: Query parameter name to pass the search term
        minChars:
          type: integer
          default: 0
          description: |
            Minimum number of characters before fetching suggestions.
            Set to 0 to fetch immediately on focus (when fetchOnFocus is true).
        debounceMs:
          type: integer
          default: 300
          description: Debounce delay in milliseconds before fetching suggestions
        fetchOnFocus:
          type: boolean
          default: false
          description: Whether to fetch all options when the field is focused
        labelField:
          type: string
          default: label
          description: The field name in the response objects to use as the display label
        valueField:
          type: string
          default: value
          description: The field name in the response objects to use as the stored value
        allowFreeText:
          type: boolean
          default: false
          description: |
            Whether to allow values that are not in the suggestions list.
            When true, users can enter and submit any text.
        multiple:
          type: boolean
          default: false
          description: |
            Whether to allow multiple selections.
            When true, users can select multiple values displayed as tags.
        params:
          type: object
          additionalProperties:
            type: string
          description: |
            Map of URL query parameter names to sibling form field names.
            When fetching autocomplete options, the current value of each
            referenced sibling field is appended as a query parameter.
            When any dependency field changes, the autocomplete clears its
            current value and invalidates the suggestion cache.
      required:
        - url
    ConfigSchema:
      type: object
      properties:
        type:
          type: string
          enum:
            - object
        properties:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ConfigProperty'
          description: Configuration properties
        required:
          type: array
          items:
            type: string
          description: Required property names
        additionalProperties:
          type: boolean
          default: false
      required:
        - type
        - properties
    TemplateVariablesConfig:
      type: object
      description: |
        Configuration for template variable autocomplete in template fields.

        ## Overview

        When a template field is connected to upstream nodes that have output schemas,
        FlowDrop automatically derives available variables for autocomplete. This config
        controls which ports provide variables and how they are presented.

        ## Variable Derivation

        Variables are derived from connected upstream nodes' **output port schemas**.
        When an output port has a `schema` property with `properties`, those properties
        become available as template variables.

        ### Default Behavior (includePortName: false)

        Schema properties are **unpacked as top-level variables**:

        ```
        HTTP Request node (output port "json" with schema):
          schema.properties: { user: {...}, orders: {...} }
                                  ↓
        Template variables: {{ user }}, {{ orders }}
        ```

        ### With includePortName: true

        Variables are **prefixed with the port name**:

        ```
        Same schema as above:
                                  ↓
        Template variables: {{ data.user }}, {{ data.orders }}
        ```

        ## Nested Property Access

        The autocomplete supports drilling into nested structures:

        - **Dot notation**: `{{ user.address.city }}`
        - **Array indices**: `{{ orders[0].product_name }}`
        - **Combined**: `{{ user.orders[0].items[1].price }}`
      properties:
        ports:
          type: array
          items:
            type: string
          description: |
            Specifies which input port IDs should provide variables for autocomplete.
            Only connections to these ports will contribute variables.

            **Behavior:**
            - If not specified: All input ports with connections are used
            - If empty array `[]`: No variables derived from ports (use with `schema` for static variables)
            - If specified: Only the listed ports contribute variables

            **Example:** A node with inputs "data", "context", and "trigger":
            - `ports: ["data"]` - Only variables from the "data" connection
            - `ports: ["data", "context"]` - Variables from both connections
            - Not specified - Variables from all non-trigger connections
          example:
            - data
            - context
        schema:
          $ref: '#/components/schemas/VariableSchema'
          description: |
            Pre-defined variable schema to provide static variables or override derived ones.

            When both `ports` and `schema` are specified, variables are **merged**:
            - Variables from connected ports are computed first
            - Static `schema` variables are added/override existing ones

            **Use cases:**
            - Provide variables that don't come from connections
            - Override labels or descriptions for derived variables
            - Add custom variables for specific use cases
        includePortName:
          type: boolean
          default: false
          description: |
            Controls how variables are named when derived from port schemas.

            **When false (default):**
            Schema properties become top-level variables directly.
            A port with schema `{ user: {...}, orders: {...} }` produces:
            - `{{ user }}`
            - `{{ orders }}`

            **When true:**
            Variables are prefixed with the input port name.
            Same schema connected to input port "data" produces:
            - `{{ data.user }}`
            - `{{ data.orders }}`

            **When to use true:**
            - Multiple input ports with potentially overlapping property names
            - You want to be explicit about data sources in templates
            - Backward compatibility with existing templates
        showHints:
          type: boolean
          default: true
          description: |
            Whether to display clickable variable hints below the editor.

            When enabled, shows a row of buttons for top-level variables that users
            can click to insert `{{ variableName }}` at the cursor position.

            Disable if the variable list is too long or not useful.
      example:
        ports:
          - data
        showHints: true
        includePortName: false
    NodePort:
      type: object
      description: |
        Defines an input or output port on a node.

        Ports are connection points where data flows between nodes. Input ports
        receive data from upstream nodes, and output ports send data to downstream nodes.

        ## Template Variable Autocomplete

        Output ports can include a `schema` property that describes the structure of
        their data. This schema is used by downstream nodes' template fields to provide
        autocomplete suggestions.

        When a template field is connected to a port with a schema, users get:
        - Autocomplete for top-level properties when typing `{{`
        - Nested property drilling when typing `.`
        - Array index suggestions when typing `[`
      properties:
        id:
          type: string
          description: Port unique identifier (used in handle IDs and variable names)
          example: json
        name:
          type: string
          description: Port display name shown in the UI
          example: JSON Response
        type:
          type: string
          enum:
            - input
            - output
            - metadata
          description: Port direction (input receives data, output sends data)
        dataType:
          $ref: '#/components/schemas/NodeDataType'
        required:
          type: boolean
          default: false
          description: Whether the port must be connected for the node to execute
        description:
          type: string
          description: Help text describing what data the port expects or provides
          example: Parsed JSON response from the HTTP request
        defaultValue:
          description: Default value used when no connection provides data
        schema:
          $ref: '#/components/schemas/PortDataSchema'
          description: |
            JSON Schema describing the structure of data on this output port.

            **Purpose:** Enables template variable autocomplete in downstream nodes.
            When a downstream node has a template field connected to this port,
            the schema's properties become available as autocomplete suggestions.

            **How it works:**
            1. Define a schema with `properties` on an output port
            2. Connect this port to a downstream node's input
            3. In the downstream node's template field, typing `{{` shows the schema's properties

            **Example:**

            ```yaml
            outputs:
              - id: json
                name: JSON Response
                type: output
                dataType: json
                schema:
                  type: object
                  properties:
                    user:
                      type: object
                      properties:
                        name: { type: string }
                        email: { type: string }
                    orders:
                      type: array
                      items:
                        type: object
                        properties:
                          id: { type: string }
                          total: { type: number }
            ```

            This enables autocomplete for:
            - `{{ user }}`, `{{ orders }}`
            - `{{ user.name }}`, `{{ user.email }}`
            - `{{ orders[0].id }}`, `{{ orders[0].total }}`
      required:
        - id
        - name
        - type
        - dataType
    VariableSchema:
      type: object
      description: |
        Schema passed to template editor for autocomplete functionality.
        Contains all available variables derived from connected upstream nodes.

        This is computed by the frontend based on:
        1. Finding all edges that connect to the current node's input ports
        2. Getting the output schemas from the source nodes' output ports
        3. Building a hierarchical variable structure for autocomplete
      properties:
        variables:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/TemplateVariable'
          description: Map of available variables keyed by variable name
      required:
        - variables
      example:
        variables:
          user:
            name: user
            type: object
            label: User Data
            properties:
              name:
                name: name
                type: string
              email:
                name: email
                type: string
          items:
            name: items
            type: array
            label: Order Items
            items:
              name: item
              type: object
              properties:
                product_name:
                  name: product_name
                  type: string
                price:
                  name: price
                  type: number
    DynamicPort:
      type: object
      description: |
        Dynamic port configuration for user-defined inputs/outputs.
        These are defined in the node's config and allow users to create
        custom input/output handles at runtime, similar to gateway branches.

        Dynamic ports are stored in `config.dynamicInputs` and `config.dynamicOutputs`
        arrays and are rendered alongside static ports defined in the node metadata.
      properties:
        name:
          type: string
          description: Unique identifier for the port (used for handle IDs and connections)
          example: custom_input_1
        label:
          type: string
          description: Display label shown in the UI
          example: Custom Input
        description:
          type: string
          description: Description of what this port accepts/provides
          example: Additional input data for processing
        dataType:
          $ref: '#/components/schemas/NodeDataType'
          description: Data type for the port (affects color and connection validation)
        required:
          type: boolean
          default: false
          description: Whether this port is required for execution
      required:
        - name
        - label
        - dataType
      example:
        name: custom_data
        label: Custom Data
        description: Additional JSON data input
        dataType: json
        required: false
    Branch:
      type: object
      description: |
        Branch configuration for gateway nodes.
        Branches define conditional output paths in gateway/switch nodes.
        Each branch creates an output handle that can be connected to downstream nodes.

        Branches are stored in `config.branches` array and support dynamic addition/removal
        through the node configuration panel.
      properties:
        name:
          type: string
          description: Unique identifier for the branch (used as handle ID)
          example: case_1
        label:
          type: string
          description: Display label shown in the UI
          example: Case 1
        description:
          type: string
          description: Description of when this branch is activated
          example: Triggered when condition A is met
        condition:
          type: string
          description: Optional condition expression for this branch
          example: value > 10
        isDefault:
          type: boolean
          default: false
          description: Whether this is the default/fallback branch
      required:
        - name
        - label
      example:
        name: high_priority
        label: High Priority
        description: Route for high priority items
        condition: priority === 'high'
        isDefault: false
    AtomUIConfig:
      type: object
      description: |
        Display/behaviour settings for minimalist `atom` nodes (e.g. Constant, Cast).
        Lives under `extensions.ui.atom`. The atom renderer reads these to decide what
        to show, and `valueTypeKey` drives the bound output port's `dataType` from
        config so connection validation matches the type the user picked.

        All fields are optional — an empty object renders a label-only pill using the
        node's `label`.
      properties:
        valueKey:
          type: string
          description: |
            Config key whose value becomes the node body text.
            Falls back to the node `label` when unset or empty.
          example: value
        valueTypeKey:
          type: string
          description: |
            Config key holding the selected value's type (a port dataType id).
            The bound output port adopts this dataType.
          example: valueType
        outputPortId:
          type: string
          description: |
            Output port id driven by `valueTypeKey`.
            Defaults to the first output port when unset.
          example: value
        shape:
          type: string
          enum:
            - pill
            - rectangle
          default: pill
          description: |
            Body shape. `pill` (default) is fully rounded; `rectangle` is lightly rounded.
          example: rectangle
        prefix:
          type: string
          description: |
            Dimmed affordance rendered before the body (e.g. `"→ "` to mark a transform).
            Stays visible while the body value ellipsizes. Hidden in the empty state.
          example: '→ '
        placeholder:
          type: string
          description: Text shown (dimmed) when the resolved body value is empty/unset.
          example: empty
        maxWidth:
          type: integer
          description: Max body width in px before the label ellipsizes.
          example: 200
      additionalProperties: false
    NodeUIExtensions:
      type: object
      description: |
        UI-related extension settings for nodes.
        Used to control visual behavior in the workflow editor.

        These settings can be defined at two levels:
        1. **Node Type Level** (`metadata.extensions.ui`): Default settings for all instances
        2. **Instance Level** (`data.extensions.ui`): Override for specific node instances

        Instance-level settings take precedence over type-level defaults.
      properties:
        hideUnconnectedHandles:
          type: boolean
          description: |
            Show/hide unconnected handles (ports) to reduce visual noise.
            When true, only ports with active connections are displayed.
            Useful for nodes with many optional ports.
          example: true
        atom:
          $ref: '#/components/schemas/AtomUIConfig'
        style:
          type: object
          additionalProperties: true
          description: Custom styles or theme overrides
          example:
            opacity: 0.8
            borderRadius: 8
      additionalProperties: true
    NodeExtensions:
      type: object
      description: |
        Custom extension properties for 3rd party integrations.
        Allows storing additional configuration and UI state data.

        Use namespaced keys (e.g., "myapp:analytics", "acme:settings") to avoid conflicts
        between different integrations.

        ## Reserved Extension Keys

        - `agentspec:component_type` — Stores the Oracle Open Agent Spec component type
          (e.g., "llm_node", "branching_node") for nodes imported from Agent Spec.
          Used for round-trip preservation during import/export.
      properties:
        ui:
          $ref: '#/components/schemas/NodeUIExtensions'
        agentspec:component_type:
          type: string
          description: |
            Agent Spec component type for round-trip preservation.
            Set automatically when importing from Agent Spec format.
          example: llm_node
      additionalProperties: true
      example:
        ui:
          hideUnconnectedHandles: true
          style:
            opacity: 0.8
        agentspec:component_type: llm_node
        myapp:analytics:
          trackUsage: true
          customField: value
    NodeMetadata:
      type: object
      description: |
        Complete metadata for a node type including ports, configuration schema, and extensions.

        ## Dynamic Port Support

        Nodes can support user-defined dynamic ports through their configSchema:
        - Add `dynamicInputs` array property to allow custom input handles
        - Add `dynamicOutputs` array property to allow custom output handles
        - Add `branches` array property for gateway nodes with conditional paths

        ## Extensions Support

        The `extensions` property allows storing UI settings and 3rd party data:
        - Use `extensions.ui.hideUnconnectedHandles` to hide unconnected ports by default
        - Use namespaced keys for custom integrations (e.g., "myapp:settings")
      properties:
        id:
          type: string
          description: Node type unique identifier
          example: calculator
        name:
          type: string
          description: Node type display name
          example: Calculator
        type:
          $ref: '#/components/schemas/NodeType'
        supportedTypes:
          type: array
          items:
            $ref: '#/components/schemas/NodeType'
          description: Array of supported rendering types
        description:
          type: string
          description: Node type description
          example: Perform mathematical operations on input data
        category:
          $ref: '#/components/schemas/NodeCategory'
        version:
          type: string
          description: Node type version
          example: 1.0.0
        icon:
          type: string
          description: Icon identifier (Material Design Icons)
          example: mdi:calculator
        color:
          type: string
          description: Node color (CSS color value)
          example: '#3b82f6'
        badge:
          type: string
          description: |
            Default badge label displayed in the node header (e.g., "TOOL", "API", "LLM").
            Currently used by tool nodes. Can be overridden per-instance via `config.instanceBadge`.
            Defaults to "TOOL" for tool nodes if not specified.
          example: API
        portDataType:
          type: string
          description: |
            Port dataType to expose on tool nodes. Defaults to "tool".
            Set to another type (e.g., "trigger") to show that port type instead.
            This allows repurposing the tool node with a custom badge and matching port type.
          example: trigger
        inputs:
          type: array
          items:
            $ref: '#/components/schemas/NodePort'
          description: |
            Static input ports defined by the node type.
            Additional dynamic inputs can be added via config.dynamicInputs.
        outputs:
          type: array
          items:
            $ref: '#/components/schemas/NodePort'
          description: |
            Static output ports defined by the node type.
            Additional dynamic outputs can be added via config.dynamicOutputs.
            For gateway nodes, branches create additional output handles.
        configSchema:
          $ref: '#/components/schemas/ConfigSchema'
        tags:
          type: array
          items:
            type: string
          description: Node tags for search and filtering
          example:
            - math
            - calculation
            - processing
        formats:
          type: array
          items:
            type: string
          description: |
            Workflow formats this node is compatible with.
            When omitted, the node is universal (compatible with all formats).
            When specified, the node only appears in the sidebar for workflows
            matching one of the listed formats.
          example:
            - agentspec
        extensions:
          $ref: '#/components/schemas/NodeExtensions'
          description: |
            Default extension properties for all instances of this node type.
            Can be overridden at the instance level via WorkflowNode.data.extensions.
      required:
        - id
        - name
        - description
        - category
        - version
        - inputs
        - outputs
    NodeConfig:
      type: object
      description: |
        Node configuration values containing all user-configured settings for a node instance.

        This object stores configuration based on the node type's `configSchema` and is used by
        the backend to:
        - **Store and retrieve** node configuration persistently
        - **Pass values** to node processors during workflow execution
        - **Persist state** across sessions

        ## Standard Properties

        Any property defined in the node's `configSchema` (e.g., model, temperature, apiKey).
        The schema defines the type, validation rules, and default values for each property.

        ## Reserved Property Names

        These property names have special meaning and trigger automatic behaviors in FlowDrop:

        ### Instance Display Overrides

        - **`instanceTitle`**: Per-instance title override (replaces the default `label` display)
        - **`instanceDescription`**: Per-instance description override (replaces `metadata.description` display)
        - **`instanceBadge`**: Per-instance badge label override (replaces the default `metadata.badge` or "TOOL" badge)

        ### Visual Type Selection

        - **`nodeType`**: Changes the visual rendering type of the node (e.g., "default", "simple", "square")

        ### Dynamic Ports

        - **`dynamicInputs`**: Array of DynamicPort for user-defined input handles
        - **`dynamicOutputs`**: Array of DynamicPort for user-defined output handles
        - **`branches`**: Array of Branch for gateway node conditional output paths

        These dynamic configuration values generate additional handles on the node
        that can be connected to other nodes in the workflow.
      properties:
        instanceTitle:
          type: string
          description: |
            Per-instance title override that replaces the default node label.
            Useful when you have multiple instances of the same node type and want
            to give each a meaningful name (e.g., "Email Summarizer" instead of "LLM Processor").

            Fallback behavior:
            - If `instanceTitle` is set → displays `instanceTitle`
            - If not set → displays `label` (from node data)
          example: Email Summarizer
        instanceDescription:
          type: string
          description: |
            Per-instance description override that replaces the default `metadata.description`.
            Useful for documenting what a specific node instance does within your workflow.

            Fallback behavior:
            - If `instanceDescription` is set → displays `instanceDescription`
            - If not set → displays `metadata.description` (from node type definition)
          example: Summarizes incoming emails into 3 bullet points
        instanceBadge:
          type: string
          description: |
            Per-instance badge label override for tool nodes.
            Replaces the default badge text shown in the node header.

            Fallback behavior:
            - If `instanceBadge` is set → displays `instanceBadge`
            - If not set → displays `metadata.badge` (from node type definition)
            - If neither set → displays "TOOL"
          example: API
        nodeType:
          type: string
          description: |
            Changes how the node is visually rendered. This allows a single node definition
            to support multiple visual representations.

            Available built-in types:
            - `default`: Standard workflow node with full details
            - `simple`: Compact layout with minimal chrome
            - `square`: Geometric square layout (icon-only)
            - `atom`: Minimal label-only pill/rectangle (uses extensions.ui.atom)
            - `tool`: Specialized style for agent tools
            - `gateway`: Branching control flow visualization
            - `terminal`: Start/end/exit node styling
            - `note`: Sticky note style for annotations
            - `idea`: Conceptual idea node for BPMN-like flow diagrams

            The node's `metadata.supportedTypes` defines which types are allowed.
            If invalid or missing, falls back to `metadata.type` or "default".
          enum:
            - default
            - simple
            - square
            - atom
            - tool
            - gateway
            - terminal
            - note
            - idea
          example: simple
        dynamicInputs:
          type: array
          items:
            $ref: '#/components/schemas/DynamicPort'
          description: User-defined dynamic input ports that appear as additional input handles
        dynamicOutputs:
          type: array
          items:
            $ref: '#/components/schemas/DynamicPort'
          description: User-defined dynamic output ports that appear as additional output handles
        branches:
          type: array
          items:
            $ref: '#/components/schemas/Branch'
          description: Gateway node branches that define conditional output paths
      additionalProperties: true
      example:
        instanceTitle: Email Summarizer
        instanceDescription: Summarizes incoming emails into 3 bullet points
        instanceBadge: LLM
        nodeType: simple
        model: gpt-4o-mini
        temperature: 0.7
        maxTokens: 1000
        apiKey: sk-...
        dynamicInputs:
          - name: extra_data
            label: Extra Data
            dataType: json
            required: false
        dynamicOutputs:
          - name: result
            label: Result
            dataType: string
        branches:
          - name: success
            label: Success
            condition: status === 200
          - name: error
            label: Error
            isDefault: true
    NodeExecutionInfo:
      type: object
      properties:
        status:
          $ref: '#/components/schemas/NodeExecutionStatus'
        executionCount:
          type: integer
          description: Total number of times this node has been executed
          example: 5
        lastExecuted:
          type: string
          format: date-time
          description: Last execution timestamp
        lastExecutionDuration:
          type: integer
          description: Last execution duration in milliseconds
          example: 1500
        lastError:
          type: string
          description: Last error message if execution failed
        isExecuting:
          type: boolean
          description: Whether the node is currently being executed
      required:
        - status
        - executionCount
        - isExecuting
    WorkflowNode:
      type: object
      description: |
        Represents a node instance in a workflow.

        Each node instance contains:
        - Position on the canvas
        - Display data (label)
        - Configuration values (config) - user-defined settings
        - Metadata from the node type definition
        - Optional execution state and extensions
      properties:
        id:
          type: string
          format: uuid
          description: Node instance UUID
        type:
          type: string
          description: Node type ID (references NodeMetadata.id)
          example: calculator
        position:
          $ref: '#/components/schemas/Position'
        deletable:
          type: boolean
          default: true
        data:
          type: object
          properties:
            label:
              type: string
              description: Node instance label
              example: Math Calculator
            config:
              $ref: '#/components/schemas/NodeConfig'
            metadata:
              $ref: '#/components/schemas/NodeMetadata'
            isProcessing:
              type: boolean
              description: Whether the node is currently processing
            error:
              type: string
              description: Error message if node execution failed
            nodeId:
              type: string
              description: Alternative node ID
            executionInfo:
              $ref: '#/components/schemas/NodeExecutionInfo'
            extensions:
              $ref: '#/components/schemas/NodeExtensions'
              description: |
                Per-instance extension properties for 3rd party integrations.
                Overrides or extends the node type extensions defined in metadata.extensions.
                Use for instance-specific UI states or custom data.

                Common use cases:
                - `extensions.ui.hideUnconnectedHandles`: Hide ports without connections
                - `extensions.ui.style`: Custom styling for this node instance
          required:
            - label
            - config
            - metadata
      required:
        - id
        - type
        - position
        - data
    WorkflowEdge:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Edge UUID
        source:
          type: string
          format: uuid
          description: Source node UUID
        target:
          type: string
          format: uuid
          description: Target node UUID
        sourceHandle:
          type: string
          description: Source port ID
        targetHandle:
          type: string
          description: Target port ID
        type:
          type: string
          description: Connection line type
          enum:
            - default
            - straight
            - step
            - smoothstep
        selectable:
          type: boolean
          default: true
        deletable:
          type: boolean
          default: true
        data:
          type: object
          properties:
            label:
              type: string
              description: Edge label
            condition:
              type: string
              description: Conditional expression for conditional edges
            metadata:
              type: object
              description: Edge metadata for API and persistence
              properties:
                edgeType:
                  type: string
                  enum:
                    - trigger
                    - tool
                    - data
                  description: Edge type for visual styling
                sourcePortDataType:
                  type: string
                  description: Data type of the source output port (e.g., tool, string, number)
            isToolConnection:
              type: boolean
              description: Whether this is a tool connection (deprecated, use metadata.edgeType instead)
            targetNodeType:
              type: string
              description: Target node type
            targetCategory:
              type: string
              description: Target node category
      required:
        - id
        - source
        - target
    WorkflowMetadata:
      type: object
      properties:
        version:
          type: string
          description: Workflow version
          example: 1.0.0
        createdAt:
          type: string
          format: date-time
          description: Creation timestamp
        updatedAt:
          type: string
          format: date-time
          description: Last update timestamp
        author:
          type: string
          description: Workflow author
          example: admin
        tags:
          type: array
          items:
            type: string
          description: Workflow tags
          example:
            - ai
            - production
        versionId:
          type: string
          description: Version control ID
        updateNumber:
          type: integer
          description: Update sequence number
        format:
          type: string
          description: |
            Workflow format identifier. Determines which node types are shown
            in the sidebar and how the workflow is exported.
            Built-in formats: 'flowdrop' (default), 'agentspec'.
            Custom formats can be registered via WorkflowFormatRegistry.
          example: flowdrop
          default: flowdrop
      required:
        - version
        - createdAt
        - updatedAt
    Workflow:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Workflow UUID
        name:
          type: string
          description: Workflow name
          example: My AI Workflow
          maxLength: 200
        description:
          type: string
          description: Workflow description
          maxLength: 1000
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowNode'
          description: Workflow nodes
        edges:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowEdge'
          description: Workflow edges
        metadata:
          $ref: '#/components/schemas/WorkflowMetadata'
        config:
          type: object
          description: Custom workflow-level configuration values. Populated when a workflowSettingsSchema is provided to the editor.
          additionalProperties: true
      required:
        - id
        - name
        - nodes
        - edges
        - metadata
    CreateWorkflowRequest:
      type: object
      properties:
        name:
          type: string
          description: Workflow name
          minLength: 1
          maxLength: 200
          example: My First Workflow
        description:
          type: string
          description: Workflow description
          maxLength: 1000
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowNode'
        edges:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowEdge'
        tags:
          type: array
          items:
            type: string
            maxLength: 50
          maxItems: 20
      required:
        - name
    UpdateWorkflowRequest:
      type: object
      properties:
        name:
          type: string
          description: Workflow name
          minLength: 1
          maxLength: 200
        description:
          type: string
          description: Workflow description
          maxLength: 1000
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowNode'
        edges:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowEdge'
        metadata:
          type: object
          properties:
            tags:
              type: array
              items:
                type: string
                maxLength: 50
              maxItems: 20
            author:
              type: string
              maxLength: 100
    JobStatus:
      type: object
      properties:
        id:
          type: string
          description: Job UUID
        node_id:
          type: string
          description: Node instance UUID
        status:
          $ref: '#/components/schemas/NodeExecutionStatus'
        execution_count:
          type: integer
          description: Number of times executed
        started:
          type: string
          format: date-time
          description: Job start time
        completed:
          type: string
          format: date-time
          description: Job completion time
        execution_time:
          type: integer
          description: Execution time in milliseconds
        error_message:
          type: string
          description: Error message if failed
    NodeStatus:
      type: object
      properties:
        status:
          $ref: '#/components/schemas/NodeExecutionStatus'
        last_executed:
          type: string
          format: date-time
        execution_time:
          type: integer
          description: Last execution time in milliseconds
        error:
          type: string
          description: Last error message
    JobStatusSummary:
      type: object
      properties:
        total:
          type: integer
          description: Total number of jobs
        pending:
          type: integer
          description: Number of pending jobs
        running:
          type: integer
          description: Number of running jobs
        completed:
          type: integer
          description: Number of completed jobs
        failed:
          type: integer
          description: Number of failed jobs
        cancelled:
          type: integer
          description: Number of cancelled jobs
        skipped:
          type: integer
          description: Number of skipped jobs
        paused:
          type: integer
          description: Number of paused jobs
        interrupted:
          type: integer
          description: Number of interrupted jobs
      required:
        - total
        - pending
        - running
        - completed
        - failed
        - cancelled
    PipelineDetailResponse:
      type: object
      properties:
        status:
          type: string
          enum:
            - pending
            - running
            - completed
            - failed
            - cancelled
            - paused
            - interrupted
          description: Overall pipeline status
        jobs:
          type: array
          items:
            $ref: '#/components/schemas/JobStatus'
          description: Individual job statuses
        node_statuses:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/NodeStatus'
          description: Node execution statuses keyed by node ID
        job_status_summary:
          $ref: '#/components/schemas/JobStatusSummary'
        kanban_config:
          $ref: '#/components/schemas/KanbanConfig'
          description: Optional server-defined kanban board layout; frontend falls back to defaults if absent
      required:
        - status
        - jobs
        - node_statuses
        - job_status_summary
    PipelineListResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                  workflow_id:
                    type: string
                  status:
                    type: string
                  created:
                    type: string
                    format: date-time
                  updated:
                    type: string
                    format: date-time
    PipelineExecutionResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: object
              properties:
                pipeline_id:
                  type: string
                  format: uuid
                status:
                  type: string
                  enum:
                    - pending
                    - running
                message:
                  type: string
    LogEntry:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
          description: Log entry timestamp
        level:
          type: string
          enum:
            - debug
            - info
            - warning
            - error
          description: Log level
        message:
          type: string
          description: Log message
        node_id:
          type: string
          description: Associated node ID
        context:
          type: object
          additionalProperties: true
          description: Additional context data
    PlaygroundSessionStatus:
      type: string
      enum:
        - idle
        - running
        - awaiting_input
        - completed
        - failed
      description: Current status of a playground session
    PlaygroundMessageRole:
      type: string
      enum:
        - user
        - assistant
        - system
        - log
      description: |
        Role of the message sender:
        - `user`: Message from the user
        - `assistant`: Response from the workflow/AI
        - `system`: System notifications
        - `log`: Execution log entries
    PlaygroundMessageLevel:
      type: string
      enum:
        - info
        - warning
        - error
        - debug
      description: Log level for log-type messages
    PlaygroundMessageStatus:
      type: string
      enum:
        - pending
        - processing
        - completed
        - failed
      description: |
        Processing status of the message:
        - `pending`: Message created, waiting to be processed
        - `processing`: Message is currently being processed
        - `completed`: Message processing completed successfully
        - `failed`: Message processing failed
    PlaygroundSession:
      type: object
      description: |
        A playground session represents an isolated test environment for a workflow.
        Sessions maintain conversation history and allow interactive testing.
      properties:
        id:
          type: string
          format: uuid
          description: Session unique identifier
        workflowId:
          type: string
          format: uuid
          description: Associated workflow ID
        name:
          type: string
          description: Session display name
          example: Test Session 1
        status:
          $ref: '#/components/schemas/PlaygroundSessionStatus'
        createdAt:
          type: string
          format: date-time
          description: Session creation timestamp
        updatedAt:
          type: string
          format: date-time
          description: Last activity timestamp
        executions:
          type: array
          description: |
            Main pipeline runs triggered within this session, ordered oldest-first.
            Sub-flow (nested) executions are intentionally excluded — they are
            surfaced only on individual messages via `parentPipelineId`. Clients rely
            on this list being main-runs-only to populate the run-switcher.
          items:
            $ref: '#/components/schemas/PlaygroundExecution'
          nullable: true
        metadata:
          type: object
          additionalProperties: true
          description: Custom session metadata
      required:
        - id
        - workflowId
        - name
        - status
        - createdAt
        - updatedAt
    PlaygroundMessage:
      type: object
      description: |
        A message in a playground session. Messages can be user inputs,
        assistant responses, system notifications, or execution logs.
      properties:
        id:
          type: string
          format: uuid
          description: Message unique identifier
        sessionId:
          type: string
          format: uuid
          description: Parent session ID
        role:
          $ref: '#/components/schemas/PlaygroundMessageRole'
        content:
          type: string
          description: Message content
        timestamp:
          type: string
          format: date-time
          description: Message timestamp
        status:
          $ref: '#/components/schemas/PlaygroundMessageStatus'
        sequenceNumber:
          type: integer
          description: |
            Incrementing sequence number for chronological ordering within a session.
            All messages (user, assistant, log) receive incrementing numbers (1, 2, 3, ...).
            Use this as the primary sort key for displaying messages in order.
          minimum: 1
        parentMessageId:
          type: string
          format: uuid
          description: Parent message ID (for linking user message to assistant response)
          nullable: true
        executionId:
          type: string
          description: Workflow execution ID that generated this message
          nullable: true
        parentPipelineId:
          type: string
          description: |
            Execution ID of the parent pipeline when this message was produced by a
            nested sub-flow. `null` for top-level (main pipeline) messages. Unlike
            the display-only `hierarchy`, this is an authoritative nesting signal:
            clients use it to keep the main pipeline in focus and exclude sub-flow
            runs from the run-switcher.
          nullable: true
        rootPipelineId:
          type: string
          description: |
            Execution ID of the top-level pipeline this message ultimately belongs
            to. Equal to `executionId` for main-pipeline messages; for sub-flow
            messages it points to the main run that triggered the sub-flow.
          nullable: true
        nodeId:
          type: string
          description: Associated node ID (for log messages)
          nullable: true
        hierarchy:
          type: array
          description: |
            Ordered hierarchy path describing where this message sits (e.g.
            workflow > sub-workflow > iteration). Display-only; rendered as a
            chevron-separated trail. The server decides the depth and content.
          items:
            $ref: '#/components/schemas/MessageHierarchyItem'
        tags:
          type: array
          description: |
            Server-emitted classification chips. When present, the client
            renders exactly these tags — there is no client-side synthesis.
          items:
            $ref: '#/components/schemas/MessageTag'
        display:
          $ref: '#/components/schemas/PlaygroundMessageDisplay'
          description: |
            Optional layout hint. When omitted, the client picks a default
            based on the message role.
        metadata:
          type: object
          properties:
            level:
              $ref: '#/components/schemas/PlaygroundMessageLevel'
            duration:
              type: integer
              description: Execution duration in milliseconds
            nodeLabel:
              type: string
              description: Human-readable node label
            outputs:
              type: object
              additionalProperties: true
              description: Node output data
          additionalProperties: true
          description: Additional message metadata
      required:
        - id
        - sessionId
        - role
        - content
        - timestamp
        - status
        - sequenceNumber
      example:
        id: be4d854d-d6b3-4242-b2ea-0008b2e059bd
        sessionId: fe5304ea-f069-433f-b0bf-945975c0b806
        role: user
        content: Hello. How are you?
        timestamp: '2026-01-19T10:03:32+01:00'
        status: completed
        sequenceNumber: 1
        parentMessageId: null
        nodeId: null
        metadata: {}
    PlaygroundInputField:
      type: object
      description: |
        Input field derived from workflow input nodes.
        Used to auto-generate input forms in the playground.
      properties:
        nodeId:
          type: string
          description: Source node ID
        fieldId:
          type: string
          description: Field identifier
        label:
          type: string
          description: Display label
        type:
          type: string
          description: Field data type
        defaultValue:
          description: Default value from node config
        required:
          type: boolean
          description: Whether the field is required
        schema:
          $ref: '#/components/schemas/ConfigProperty'
          description: JSON Schema for the field
      required:
        - nodeId
        - fieldId
        - label
        - type
        - required
    PlaygroundMessageRequest:
      type: object
      description: Request body for sending a message to the playground
      properties:
        content:
          type: string
          description: Message content (typically user input)
          maxLength: 10000
        inputs:
          type: object
          additionalProperties: true
          description: Additional input values for workflow nodes
      required:
        - content
    PlaygroundSessionResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/PlaygroundSession'
    PlaygroundSessionsResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/PlaygroundSession'
    PlaygroundMessageResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/PlaygroundMessage'
    PlaygroundMessagesResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/PlaygroundMessage'
            hasMore:
              type: boolean
              description: |
                Whether more recent messages remain after this page (forward
                pagination via `since`).
            hasOlder:
              type: boolean
              description: |
                Whether older messages exist before the first message in this page.
                Set on `latest`/`before` (backward pagination) responses so a chat
                surface knows whether to keep loading on scroll-up.
            sessionStatus:
              $ref: '#/components/schemas/PlaygroundSessionStatus'
              description: Current session status (useful for polling)
    ChatMessageRole:
      type: string
      description: Role of the message sender
      enum:
        - user
        - assistant
      example: user
    ChatHistoryMessage:
      type: object
      description: A single message in the chat conversation history
      required:
        - role
        - content
      properties:
        role:
          $ref: '#/components/schemas/ChatMessageRole'
        content:
          type: string
          description: The message text content
          example: Add a new processing node called "transform"
    ChatRequest:
      type: object
      description: Request payload for sending a chat message
      required:
        - message
        - workflowState
      properties:
        message:
          type: string
          description: The user's natural language message
          example: Add a node called "transform" and connect it to the start node
        workflowState:
          type: object
          description: |
            Serialized current workflow state including nodes and edges.
            This gives the LLM context about the current workflow being edited.
          additionalProperties: true
        history:
          type: array
          description: Optional conversation history for multi-turn context
          items:
            $ref: '#/components/schemas/ChatHistoryMessage'
    ChatResponse:
      type: object
      description: |
        Response from the chat endpoint containing the LLM's reply.
        The content may include markdown formatting and fenced code blocks
        with DSL commands (```flowdrop blocks).
      required:
        - content
      properties:
        content:
          type: string
          description: |
            The LLM's response content. May contain markdown and
            ```flowdrop fenced code blocks with DSL commands.
          example: |
            I'll add a processing node and connect it to your start node.

            ```flowdrop
            add transform processing
            connect start:output transform:input
            ```
        conversationId:
          type: string
          description: Optional conversation ID for backend session tracking
          example: conv-abc123
    ChatMessagesResponse:
      type: object
      description: Wrapped response for chat message send
      properties:
        success:
          type: boolean
          example: true
        data:
          $ref: '#/components/schemas/ChatResponse'
    ChatHistoryResponse:
      type: object
      description: Wrapped response for chat history retrieval
      properties:
        success:
          type: boolean
          example: true
        data:
          type: array
          items:
            $ref: '#/components/schemas/ChatHistoryMessage'
    InterruptType:
      type: string
      enum:
        - confirmation
        - choice
        - text
        - form
        - review
      description: |
        Type of interrupt prompt:
        - `confirmation`: Yes/No approval prompt
        - `choice`: Single or multiple selection from options
        - `text`: Free-form text input
        - `form`: JSON Schema-based form
        - `review`: Review proposed field changes (accept/reject individually)
    InterruptStatus:
      type: string
      enum:
        - pending
        - resolved
        - cancelled
      description: |
        Current status of the interrupt:
        - `pending`: Awaiting user response
        - `resolved`: User submitted a response
        - `cancelled`: Interrupt was cancelled
    ChoiceOption:
      type: object
      description: Option for choice-type interrupts
      properties:
        value:
          type: string
          description: Value to submit when selected
          example: option1
        label:
          type: string
          description: Display label for the option
          example: Option 1
        description:
          type: string
          description: Optional description for the option
          example: This is the first option
      required:
        - value
        - label
    ConfirmationInterruptConfig:
      type: object
      description: Configuration for confirmation-type interrupts
      properties:
        message:
          type: string
          description: Prompt message to display
          example: Do you approve this action?
        confirm_label:
          type: string
          description: Label for confirm button
          default: 'Yes'
          example: Approve
        cancel_label:
          type: string
          description: Label for cancel/reject button
          default: 'No'
          example: Reject
      required:
        - message
    ChoiceInterruptConfig:
      type: object
      description: Configuration for choice-type interrupts
      properties:
        message:
          type: string
          description: Prompt message to display
          example: Select your preferred option
        options:
          type: array
          items:
            $ref: '#/components/schemas/ChoiceOption'
          description: Available options to choose from
          minItems: 1
        multiple:
          type: boolean
          default: false
          description: Whether multiple selections are allowed
        min_selections:
          type: integer
          minimum: 0
          description: Minimum number of selections required
        max_selections:
          type: integer
          minimum: 1
          description: Maximum number of selections allowed
      required:
        - message
        - options
    TextInterruptConfig:
      type: object
      description: Configuration for text-type interrupts
      properties:
        message:
          type: string
          description: Prompt message to display
          example: Please provide additional details
        placeholder:
          type: string
          description: Placeholder text for input field
          example: Enter your response...
        multiline:
          type: boolean
          default: false
          description: Whether to use a textarea for multiline input
        min_length:
          type: integer
          minimum: 0
          description: Minimum text length required
        max_length:
          type: integer
          minimum: 1
          description: Maximum text length allowed
        default_value:
          type: string
          description: Default value to pre-fill
      required:
        - message
    FormInterruptConfig:
      type: object
      description: Configuration for form-type interrupts
      properties:
        message:
          type: string
          description: Prompt message to display above the form
          example: Please fill in the required information
        schema:
          $ref: '#/components/schemas/ConfigSchema'
          description: JSON Schema defining the form structure
        default_values:
          type: object
          additionalProperties: true
          description: Default values for form fields
      required:
        - message
        - schema
    ReviewChange:
      type: object
      description: A single field change proposed for review
      properties:
        field:
          type: string
          description: Field identifier (machine key)
          example: title
        label:
          type: string
          description: Human-readable field label
          example: Page Title
        original:
          description: Original value before the proposed change
          example: About Us
        proposed:
          description: Proposed new value
          example: About Our Company
      required:
        - field
        - label
        - original
        - proposed
    ReviewInterruptConfig:
      type: object
      description: Configuration for review-type interrupts. Displays a list of proposed field changes for the user to accept or reject individually.
      properties:
        message:
          type: string
          description: Prompt message to display above the review
          example: Please review the following changes
        changes:
          type: array
          items:
            $ref: '#/components/schemas/ReviewChange'
          description: List of field changes to review
          minItems: 1
        accept_all_label:
          type: string
          description: Label for the "Accept All" button
          default: Accept All
        reject_all_label:
          type: string
          description: Label for the "Reject All" button
          default: Reject All
        submit_label:
          type: string
          description: Label for the submit button
          default: Submit Review
      required:
        - message
        - changes
    ReviewFieldDecision:
      type: object
      description: Per-field decision in a review resolution
      properties:
        accepted:
          type: boolean
          description: Whether the proposed change was accepted
        value:
          description: The effective value (proposed if accepted, original if rejected)
      required:
        - accepted
        - value
    ReviewResolution:
      type: object
      description: Resolution value for review-type interrupts
      properties:
        decisions:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ReviewFieldDecision'
          description: Map of field identifier to the user's decision
        summary:
          type: object
          properties:
            accepted:
              type: integer
              description: Number of accepted changes
            rejected:
              type: integer
              description: Number of rejected changes
            total:
              type: integer
              description: Total number of changes
          required:
            - accepted
            - rejected
            - total
      required:
        - decisions
        - summary
      example:
        decisions:
          title:
            accepted: true
            value: About Our Company
          meta_description:
            accepted: false
            value: Learn about us
        summary:
          accepted: 1
          rejected: 1
          total: 2
    Interrupt:
      type: object
      description: |
        Represents a Human-in-the-Loop interrupt request.
        Interrupts are created when workflow execution requires user input.
      properties:
        id:
          type: string
          format: uuid
          description: Interrupt unique identifier
        messageId:
          type: string
          format: uuid
          description: Associated playground message ID
        type:
          $ref: '#/components/schemas/InterruptType'
        status:
          $ref: '#/components/schemas/InterruptStatus'
        nodeId:
          type: string
          description: ID of the node that created the interrupt
        executionId:
          type: string
          description: Workflow execution ID
        config:
          oneOf:
            - $ref: '#/components/schemas/ConfirmationInterruptConfig'
            - $ref: '#/components/schemas/ChoiceInterruptConfig'
            - $ref: '#/components/schemas/TextInterruptConfig'
            - $ref: '#/components/schemas/FormInterruptConfig'
            - $ref: '#/components/schemas/ReviewInterruptConfig'
          description: Type-specific configuration
        allowCancel:
          type: boolean
          default: true
          description: Whether the interrupt can be cancelled
        response:
          description: User's response (set after resolution)
        response_time:
          type: string
          format: date-time
          description: When the interrupt was resolved
        user_id:
          type: string
          description: ID of the user who resolved the interrupt
        createdAt:
          type: string
          format: date-time
          description: When the interrupt was created
      required:
        - id
        - type
        - status
        - nodeId
        - executionId
        - config
        - allowCancel
    InterruptMessageMetadata:
      type: object
      description: |
        Metadata structure for interrupt requests embedded in playground messages.
        When a message contains this metadata, the frontend should render an interrupt prompt.
      properties:
        type:
          type: string
          enum:
            - interrupt_request
          description: Must be "interrupt_request" to identify as interrupt
        interrupt_id:
          type: string
          format: uuid
          description: Interrupt unique identifier
        interrupt_type:
          $ref: '#/components/schemas/InterruptType'
        node_id:
          type: string
          description: ID of the node that created the interrupt
        execution_id:
          type: string
          description: Workflow execution ID
        message:
          type: string
          description: Prompt message to display
        allowCancel:
          type: boolean
          default: true
          description: Whether the interrupt can be cancelled
        confirm_label:
          type: string
          description: Label for confirm button (confirmation type)
        cancel_label:
          type: string
          description: Label for cancel button (confirmation type)
        options:
          type: array
          items:
            $ref: '#/components/schemas/ChoiceOption'
          description: Available options (choice type)
        multiple:
          type: boolean
          description: Allow multiple selections (choice type)
        min_selections:
          type: integer
          description: Minimum selections (choice type)
        max_selections:
          type: integer
          description: Maximum selections (choice type)
        placeholder:
          type: string
          description: Input placeholder (text type)
        multiline:
          type: boolean
          description: Use multiline input (text type)
        min_length:
          type: integer
          description: Minimum text length (text type)
        max_length:
          type: integer
          description: Maximum text length (text type)
        default_value:
          description: Default value (text type)
        schema:
          $ref: '#/components/schemas/ConfigSchema'
          description: Form schema (form type)
        default_values:
          type: object
          description: Form default values (form type)
        changes:
          type: array
          items:
            $ref: '#/components/schemas/ReviewChange'
          description: List of field changes to review (review type)
        accept_all_label:
          type: string
          description: Label for "Accept All" button (review type)
        reject_all_label:
          type: string
          description: Label for "Reject All" button (review type)
        submit_label:
          type: string
          description: Label for submit button (review type)
      required:
        - type
        - interrupt_id
        - interrupt_type
        - node_id
        - execution_id
      example:
        type: interrupt_request
        interrupt_id: 550e8400-e29b-41d4-a716-446655440001
        interrupt_type: confirmation
        node_id: approval-node
        execution_id: 550e8400-e29b-41d4-a716-446655440002
        message: Do you approve this action?
        confirm_label: Approve
        cancel_label: Reject
        allowCancel: true
    InterruptResolveRequest:
      type: object
      description: Request body for resolving an interrupt
      properties:
        value:
          description: |
            User's response. Type depends on interrupt type:
            - confirmation: boolean
            - choice: string or string[]
            - text: string
            - form: object
            - review: ReviewResolution (decisions map + summary)
      required:
        - value
    InterruptResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/Interrupt'
    InterruptListResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Interrupt'
    AgentSpecComponentType:
      type: string
      enum:
        - agent
        - flow
        - start_node
        - end_node
        - llm_node
        - api_node
        - agent_node
        - flow_node
        - map_node
        - branching_node
        - tool_node
        - server_tool
        - client_tool
        - remote_tool
        - llm_config
      description: All possible Agent Spec component_type values
    AgentSpecNodeComponentType:
      type: string
      enum:
        - start_node
        - end_node
        - llm_node
        - api_node
        - agent_node
        - flow_node
        - map_node
        - branching_node
        - tool_node
      description: |
        Agent Spec node component_type discriminator.

        Determines the node's behavior and available configuration:
        - `start_node` — Graph entry point
        - `end_node` — Graph exit point
        - `llm_node` — LLM text generation
        - `api_node` — HTTP API call
        - `agent_node` — Multi-round agent conversation
        - `flow_node` — Nested flow execution
        - `map_node` — Map-reduce operation
        - `branching_node` — Conditional routing
        - `tool_node` — Tool execution
    AgentSpecToolComponentType:
      type: string
      enum:
        - server_tool
        - client_tool
        - remote_tool
      description: |
        Agent Spec tool component_type discriminator.

        - `server_tool` — Executed in the same runtime environment
        - `client_tool` — Executed by the client, results returned to runtime
        - `remote_tool` — Triggered via RPC/REST calls
    AgentSpecProperty:
      type: object
      description: |
        JSON Schema-based input/output property definition.
        Uses JSON Schema types and structure for describing data shape.
        Placeholder syntax `{{variable_name}}` generates implicit input properties.
      properties:
        title:
          type: string
          description: Property name (used as identifier in edges and templates)
          example: user_query
        type:
          type: string
          description: JSON Schema type
          example: string
          enum:
            - string
            - number
            - integer
            - boolean
            - array
            - object
        description:
          type: string
          description: Human-readable description
        default:
          description: Default value
        enum:
          type: array
          items: {}
          description: Allowed values (JSON Schema enum)
        items:
          $ref: '#/components/schemas/AgentSpecProperty'
          description: Array item schema (for type=array)
        properties:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/AgentSpecProperty'
          description: Object property schemas (for type=object)
        required:
          type: array
          items:
            type: string
          description: Required properties (for type=object)
      required:
        - title
        - type
    AgentSpecBranch:
      type: object
      description: Branch definition for BranchingNode conditional routing
      properties:
        name:
          type: string
          description: Branch name (used as from_branch in ControlFlowEdge)
          example: high_priority
        condition:
          type: string
          description: Condition expression for this branch
          example: '{{priority}} == "high"'
        description:
          type: string
          description: Human-readable description
      required:
        - name
    AgentSpecNode:
      description: |
        Union of all Agent Spec node types. Discriminated by `component_type`.
      oneOf:
        - $ref: '#/components/schemas/AgentSpecStartNode'
        - $ref: '#/components/schemas/AgentSpecEndNode'
        - $ref: '#/components/schemas/AgentSpecLLMNode'
        - $ref: '#/components/schemas/AgentSpecAPINode'
        - $ref: '#/components/schemas/AgentSpecAgentNode'
        - $ref: '#/components/schemas/AgentSpecFlowNode'
        - $ref: '#/components/schemas/AgentSpecMapNode'
        - $ref: '#/components/schemas/AgentSpecBranchingNode'
        - $ref: '#/components/schemas/AgentSpecToolNode'
      discriminator:
        propertyName: component_type
        mapping:
          start_node: '#/components/schemas/AgentSpecStartNode'
          end_node: '#/components/schemas/AgentSpecEndNode'
          llm_node: '#/components/schemas/AgentSpecLLMNode'
          api_node: '#/components/schemas/AgentSpecAPINode'
          agent_node: '#/components/schemas/AgentSpecAgentNode'
          flow_node: '#/components/schemas/AgentSpecFlowNode'
          map_node: '#/components/schemas/AgentSpecMapNode'
          branching_node: '#/components/schemas/AgentSpecBranchingNode'
          tool_node: '#/components/schemas/AgentSpecToolNode'
    AgentSpecStartNode:
      allOf:
        - $ref: '#/components/schemas/AgentSpecNodeBase'
        - type: object
          properties:
            component_type:
              type: string
              enum:
                - start_node
          description: Graph entry point node
    AgentSpecEndNode:
      allOf:
        - $ref: '#/components/schemas/AgentSpecNodeBase'
        - type: object
          properties:
            component_type:
              type: string
              enum:
                - end_node
          description: Graph exit point node
    AgentSpecLLMNode:
      allOf:
        - $ref: '#/components/schemas/AgentSpecNodeBase'
        - type: object
          properties:
            component_type:
              type: string
              enum:
                - llm_node
            llm_config:
              description: LLM configuration (inline object or $component_ref string)
              oneOf:
                - $ref: '#/components/schemas/AgentSpecLLMConfig'
                - type: string
                  description: Component reference (e.g., "$component_ref:my_llm")
            system_prompt:
              type: string
              description: System prompt template (supports {{variable}} syntax)
            prompt_template:
              type: string
              description: User prompt template (supports {{variable}} syntax)
            output_schema:
              type: object
              additionalProperties: true
              description: Output JSON Schema for structured output
          description: LLM text generation node
    AgentSpecAPINode:
      allOf:
        - $ref: '#/components/schemas/AgentSpecNodeBase'
        - type: object
          properties:
            component_type:
              type: string
              enum:
                - api_node
            endpoint:
              type: string
              description: API endpoint URL
              example: https://api.example.com/v1/data
            method:
              type: string
              description: HTTP method
              enum:
                - GET
                - POST
                - PUT
                - DELETE
                - PATCH
              example: POST
            headers:
              type: object
              additionalProperties:
                type: string
              description: Request headers
            body:
              type: object
              additionalProperties: true
              description: Request body template
          description: HTTP API call node
    AgentSpecAgentNode:
      allOf:
        - $ref: '#/components/schemas/AgentSpecNodeBase'
        - type: object
          properties:
            component_type:
              type: string
              enum:
                - agent_node
            agent:
              description: Agent reference ($component_ref or inline)
              oneOf:
                - $ref: '#/components/schemas/AgentSpecAgent'
                - type: string
          description: Multi-round agent conversation node
    AgentSpecFlowNode:
      allOf:
        - $ref: '#/components/schemas/AgentSpecNodeBase'
        - type: object
          properties:
            component_type:
              type: string
              enum:
                - flow_node
            flow:
              description: Flow reference ($component_ref or inline)
              oneOf:
                - $ref: '#/components/schemas/AgentSpecFlow'
                - type: string
          description: Nested flow execution node
    AgentSpecMapNode:
      allOf:
        - $ref: '#/components/schemas/AgentSpecNodeBase'
        - type: object
          properties:
            component_type:
              type: string
              enum:
                - map_node
            input_collection:
              type: string
              description: Input collection property name
            output_collection:
              type: string
              description: Output collection property name
            map_flow:
              description: Flow or node to execute per item ($component_ref or inline)
              oneOf:
                - $ref: '#/components/schemas/AgentSpecFlow'
                - type: string
          description: Map-reduce operation node
    AgentSpecBranchingNode:
      allOf:
        - $ref: '#/components/schemas/AgentSpecNodeBase'
        - type: object
          properties:
            component_type:
              type: string
              enum:
                - branching_node
            branches:
              type: array
              items:
                $ref: '#/components/schemas/AgentSpecBranch'
              description: Branch definitions with conditions
          required:
            - branches
          description: Conditional routing node
    AgentSpecToolNode:
      allOf:
        - $ref: '#/components/schemas/AgentSpecNodeBase'
        - type: object
          properties:
            component_type:
              type: string
              enum:
                - tool_node
            tool:
              description: Tool reference ($component_ref or inline)
              oneOf:
                - $ref: '#/components/schemas/AgentSpecServerTool'
                - $ref: '#/components/schemas/AgentSpecClientTool'
                - $ref: '#/components/schemas/AgentSpecRemoteTool'
                - type: string
          description: Tool execution node
    AgentSpecControlFlowEdge:
      type: object
      description: |
        Control flow edge — defines execution order between nodes.
        Multiple control flow connections from the same branch are prohibited.
      properties:
        name:
          type: string
          description: Edge name (identifier)
          example: start_to_process
        from_node:
          type: string
          description: Source node name
          example: start
        to_node:
          type: string
          description: Target node name
          example: process_input
        from_branch:
          type: string
          nullable: true
          description: Source branch name (null = default "next" branch)
          example: high_priority
      required:
        - name
        - from_node
        - to_node
    AgentSpecDataFlowEdge:
      type: object
      description: |
        Data flow edge — routes data between node outputs and inputs.
        Maps a specific output property of a source node to a specific
        input property of a destination node.
      properties:
        name:
          type: string
          description: Edge name (identifier)
          example: query_to_llm
        source_node:
          type: string
          description: Source node name
          example: process_input
        source_output:
          type: string
          description: Source output property title
          example: processed_text
        destination_node:
          type: string
          description: Destination node name
          example: llm_generate
        destination_input:
          type: string
          description: Destination input property title
          example: prompt
      required:
        - name
        - source_node
        - source_output
        - destination_node
        - destination_input
    AgentSpecFlow:
      type: object
      description: |
        Agent Spec Flow — a directed, potentially cyclic graph of nodes.
        Flows function as "subroutines" encapsulating repeatable processes.
        They separate control-flow (execution order) from data-flow (data routing).
      properties:
        component_type:
          type: string
          enum:
            - flow
        name:
          type: string
          description: Flow name
          example: document_processing
        description:
          type: string
          description: Human-readable description
        start_node:
          type: string
          description: Reference to the StartNode name
          example: start
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecNode'
          description: All nodes in the flow
        control_flow_connections:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecControlFlowEdge'
          description: Execution order edges
        data_flow_connections:
          type: array
          nullable: true
          items:
            $ref: '#/components/schemas/AgentSpecDataFlowEdge'
          description: |
            Data routing edges. When null, data flows by matching
            input/output property names across connected nodes.
        metadata:
          type: object
          additionalProperties: true
          description: Extension metadata
      required:
        - component_type
        - name
        - start_node
        - nodes
        - control_flow_connections
    AgentSpecServerTool:
      type: object
      description: Tool executed in the same runtime environment
      properties:
        component_type:
          type: string
          enum:
            - server_tool
        name:
          type: string
          description: Tool name
          example: web_search
        description:
          type: string
          description: Human-readable description
        inputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
        outputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
        function_name:
          type: string
          description: Function name or module path
          example: tools.web_search
        metadata:
          type: object
          additionalProperties: true
      required:
        - component_type
        - name
    AgentSpecClientTool:
      type: object
      description: Tool executed by the client, results returned to runtime
      properties:
        component_type:
          type: string
          enum:
            - client_tool
        name:
          type: string
          description: Tool name
        description:
          type: string
        inputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
        outputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
        metadata:
          type: object
          additionalProperties: true
      required:
        - component_type
        - name
    AgentSpecRemoteTool:
      type: object
      description: Tool triggered via RPC/REST calls
      properties:
        component_type:
          type: string
          enum:
            - remote_tool
        name:
          type: string
          description: Tool name
        description:
          type: string
        inputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
        outputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
        endpoint:
          type: string
          description: Remote endpoint URL
        method:
          type: string
          description: HTTP method
        headers:
          type: object
          additionalProperties:
            type: string
          description: Request headers
        metadata:
          type: object
          additionalProperties: true
      required:
        - component_type
        - name
    AgentSpecTool:
      description: Union of all Agent Spec tool types
      oneOf:
        - $ref: '#/components/schemas/AgentSpecServerTool'
        - $ref: '#/components/schemas/AgentSpecClientTool'
        - $ref: '#/components/schemas/AgentSpecRemoteTool'
      discriminator:
        propertyName: component_type
        mapping:
          server_tool: '#/components/schemas/AgentSpecServerTool'
          client_tool: '#/components/schemas/AgentSpecClientTool'
          remote_tool: '#/components/schemas/AgentSpecRemoteTool'
    AgentSpecLLMConfig:
      type: object
      description: LLM model configuration
      properties:
        component_type:
          type: string
          enum:
            - llm_config
        name:
          type: string
          description: Configuration name
          example: gpt4_config
        model_id:
          type: string
          description: Model identifier (e.g., "gpt-4o", "claude-sonnet-4-5-20250929")
          example: gpt-4o
        provider:
          type: string
          description: Provider name (e.g., "openai", "anthropic")
          example: openai
        url:
          type: string
          description: API endpoint URL
        parameters:
          type: object
          additionalProperties: true
          description: Generation parameters (temperature, max_tokens, etc.)
          example:
            temperature: 0.7
            max_tokens: 2048
        metadata:
          type: object
          additionalProperties: true
      required:
        - component_type
        - name
        - model_id
    AgentSpecAgent:
      type: object
      description: |
        Agent Spec Agent — top-level conversational AI system.
        Serves as the entry point and holds shared resources like
        tools, memory, and LLM configuration.
      properties:
        component_type:
          type: string
          enum:
            - agent
        name:
          type: string
          description: Agent name
          example: customer_support_agent
        description:
          type: string
          description: Human-readable description
        inputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
        outputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
        tools:
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/AgentSpecTool'
              - type: string
                description: Component reference string
          description: Available tools (inline or $component_ref strings)
        llm_config:
          description: LLM configuration (inline or $component_ref string)
          oneOf:
            - $ref: '#/components/schemas/AgentSpecLLMConfig'
            - type: string
        system_prompt:
          type: string
          description: System prompt template
        metadata:
          type: object
          additionalProperties: true
      required:
        - component_type
        - name
    AgentSpecDocument:
      type: object
      description: |
        Top-level Agent Spec document. Contains a flow and/or agent
        definition along with shared tool and LLM configuration declarations.
      properties:
        agent:
          $ref: '#/components/schemas/AgentSpecAgent'
        flow:
          $ref: '#/components/schemas/AgentSpecFlow'
        tools:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecTool'
          description: Shared tool declarations
        llm_configs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecLLMConfig'
          description: Shared LLM configurations
        metadata:
          type: object
          additionalProperties: true
          description: Document-level metadata
    AgentSpecValidationResult:
      type: object
      description: Result of validating a workflow for Agent Spec export
      properties:
        valid:
          type: boolean
          description: Whether the workflow is valid for Agent Spec export
        errors:
          type: array
          items:
            type: string
          description: Validation errors (must be fixed before export)
        warnings:
          type: array
          items:
            type: string
          description: Validation warnings (may affect runtime behavior)
      required:
        - valid
    AgentSpecExecutionRequest:
      type: object
      description: Request to execute an Agent Spec flow on a runtime
      properties:
        flow:
          $ref: '#/components/schemas/AgentSpecFlow'
        inputs:
          type: object
          additionalProperties: true
          description: Initial input values for the flow
          example:
            user_query: What is the weather today?
      required:
        - flow
    AgentSpecExecutionResponse:
      type: object
      description: Response after starting an Agent Spec execution
      properties:
        execution_id:
          type: string
          description: Unique execution ID from the runtime
          example: exec-abc-123
        id:
          type: string
          description: Alternative execution ID field
        status:
          type: string
          enum:
            - running
            - completed
            - failed
            - cancelled
          description: Initial execution status
      required:
        - execution_id
    AgentSpecExecutionStatus:
      type: object
      description: Status of an Agent Spec runtime execution
      properties:
        execution_id:
          type: string
          description: Execution ID
        status:
          type: string
          enum:
            - running
            - completed
            - success
            - failed
            - error
            - cancelled
          description: Current execution status
        execution_status:
          type: string
          description: Alternative status field
        node_statuses:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/AgentSpecNodeStatus'
          description: Per-node execution status (keyed by node name)
        nodes:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/AgentSpecNodeStatus'
          description: Alternative per-node status field
        error:
          type: string
          description: Error message if execution failed
        message:
          type: string
          description: Alternative error message field
    AgentSpecNodeStatus:
      type: object
      description: Execution status for a single node in an Agent Spec runtime
      properties:
        status:
          type: string
          description: Node execution status
          enum:
            - idle
            - pending
            - queued
            - running
            - executing
            - completed
            - success
            - done
            - failed
            - error
            - cancelled
            - canceled
            - skipped
        state:
          type: string
          description: Alternative status field
        execution_count:
          type: integer
          description: Number of times this node has been executed
        started_at:
          type: string
          format: date-time
          description: When execution started
        duration_ms:
          type: number
          description: Execution duration in milliseconds
        error:
          type: string
          description: Error message if node failed
    AgentSpecExecutionResults:
      type: object
      description: Results from a completed Agent Spec execution
      additionalProperties: true
      example:
        response: The weather today is sunny with a high of 72°F.
        confidence: 0.95
    NodesResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/NodeMetadata'
    NodeTypeResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/NodeMetadata'
    PortConfigResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/PortConfig'
    CategoriesResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/CategoryDefinition'
    WorkflowsResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Workflow'
    WorkflowResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/Workflow'
    ValidationResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: object
              properties:
                valid:
                  type: boolean
                  description: Whether the workflow is valid
                errors:
                  type: array
                  items:
                    type: string
                  description: Validation errors
                warnings:
                  type: array
                  items:
                    type: string
                  description: Validation warnings
                suggestions:
                  type: array
                  items:
                    type: string
                  description: Improvement suggestions
    AgentSpecFlowResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/AgentSpecFlow'
    AgentSpecDocumentResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/AgentSpecDocument'
    AgentSpecValidationResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/AgentSpecValidationResult'
    AgentSpecExecutionStatusResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/AgentSpecExecutionStatus'
    AgentSpecAgentsResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/AgentSpecRuntimeAgent'
    AgentSpecToolsResponse:
      allOf:
        - $ref: '#/components/schemas/ApiResponse'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/AgentSpecRuntimeTool'
    PortDataSchema:
      type: object
      description: |
        JSON Schema describing the structure of data on an output port.
        Follows JSON Schema draft-07 specification.

        ## Purpose

        Enables template variable autocomplete in downstream nodes by describing
        the shape of data that flows through the port.

        ## Supported Features

        - **Objects**: Define `properties` to enable dot notation drilling
        - **Arrays**: Define `items` to enable index access and item property drilling
        - **Nested structures**: Combine objects and arrays for deep drilling
        - **Metadata**: Use `title` and `description` for autocomplete tooltips

        ## Example

        A schema describing an API response with user data and orders:

        ```yaml
        type: object
        properties:
          user:
            type: object
            title: User
            description: The authenticated user
            properties:
              id: { type: integer }
              name: { type: string, description: "User's full name" }
              email: { type: string }
              address:
                type: object
                properties:
                  city: { type: string }
                  country: { type: string }
          orders:
            type: array
            title: Orders
            description: User's order history
            items:
              type: object
              properties:
                order_id: { type: string }
                total: { type: number }
                status: { type: string }
        ```

        This enables template patterns like:
        - `{{ user.name }}` - Access user's name
        - `{{ user.address.city }}` - Nested property access
        - `{{ orders[0].total }}` - First order's total
        - `{{ orders[0].status }}` - First order's status
      properties:
        type:
          type: string
          enum:
            - object
            - array
            - string
            - number
            - integer
            - boolean
          description: |
            The JSON Schema type. Use `object` for nested properties,
            `array` for lists with `items` schema.
        title:
          type: string
          description: |
            Human-readable title shown in autocomplete dropdown.
            If not provided, the property name is used.
        description:
          type: string
          description: |
            Description shown as tooltip in autocomplete.
            Helps users understand what data the property contains.
        properties:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/PortDataSchema'
          description: Property schemas for object types
        items:
          $ref: '#/components/schemas/PortDataSchema'
          description: Item schema for array types
        required:
          type: array
          items:
            type: string
          description: Required property names
      example:
        type: object
        properties:
          user:
            type: object
            title: User
            description: User information
            properties:
              id:
                type: integer
                description: User ID
              name:
                type: string
                description: User full name
              email:
                type: string
                description: User email address
              address:
                type: object
                title: Address
                properties:
                  street:
                    type: string
                  city:
                    type: string
                  country:
                    type: string
          orders:
            type: array
            title: Orders
            description: List of user orders
            items:
              type: object
              properties:
                order_id:
                  type: string
                product_name:
                  type: string
                quantity:
                  type: integer
                price:
                  type: number
    TemplateVariable:
      type: object
      description: |
        Represents a variable available for template interpolation.
        Used by the template editor for autocomplete suggestions.

        Supports hierarchical drilling:
        - Objects have `properties` for dot notation (e.g., `user.name`)
        - Arrays have `items` for index access (e.g., `items[0].name`)
      properties:
        name:
          type: string
          description: Variable name (used in template as {{ name }})
          example: user
        label:
          type: string
          description: Display label for the variable in autocomplete dropdown
          example: User Data
        description:
          type: string
          description: Description shown in autocomplete tooltip
          example: User information from upstream node
        type:
          type: string
          enum:
            - string
            - number
            - integer
            - boolean
            - array
            - object
            - float
            - mixed
          description: Data type of the variable
        properties:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/TemplateVariable'
          description: For objects - child properties accessible via dot notation
        items:
          $ref: '#/components/schemas/TemplateVariable'
          description: For arrays - schema of array items accessible via index notation
        sourcePort:
          type: string
          description: Source port ID this variable comes from
        sourceNode:
          type: string
          description: Source node ID
      required:
        - name
        - type
      example:
        name: user
        label: User Data
        type: object
        properties:
          name:
            name: name
            type: string
            label: User Name
          email:
            name: email
            type: string
            label: Email Address
          address:
            name: address
            type: object
            label: Address
            properties:
              city:
                name: city
                type: string
                label: City
              country:
                name: country
                type: string
                label: Country
    KanbanColumnDef:
      type: object
      properties:
        key:
          type: string
          description: Unique column identifier
        label:
          type: string
          description: Display label for the column
        statuses:
          type: array
          items:
            $ref: '#/components/schemas/NodeExecutionStatus'
          description: Node statuses that belong to this column
        icon:
          type: string
          description: Iconify icon name (e.g. mdi:clock-outline)
        color:
          type: string
          description: CSS color value for the column accent (e.g. var(--fd-warning) or
      required:
        - key
        - label
        - statuses
    KanbanConfig:
      type: object
      properties:
        columns:
          type: array
          items:
            $ref: '#/components/schemas/KanbanColumnDef'
          description: Ordered list of kanban columns to display
      required:
        - columns
    PlaygroundExecution:
      type: object
      description: A single pipeline execution associated with a playground session
      properties:
        id:
          type: string
          description: Pipeline/execution ID
        startedAt:
          type: string
          format: date-time
          description: When the execution started
        status:
          type: string
          enum:
            - running
            - completed
            - failed
          description: Current execution status
      required:
        - id
        - startedAt
        - status
    MessageHierarchyItem:
      type: object
      description: |
        A single node on a message's hierarchy path. Rendered in document order
        separated by chevrons. Display-only — this is not a navigation breadcrumb.
      properties:
        id:
          type: string
          description: Stable identifier (used for keying)
        label:
          type: string
          description: Display label
        icon:
          type: string
          description: Optional iconify icon id (e.g. "mdi:graph")
      required:
        - id
        - label
    MessageTagColor:
      type: string
      enum:
        - muted
        - primary
        - success
        - warning
        - error
        - info
      description: Semantic color hook for a MessageTag
    MessageTagVariant:
      type: string
      enum:
        - subtle
        - solid
        - outline
      description: Visual emphasis style for a MessageTag
    MessageTag:
      type: object
      description: |
        A server-emitted classification chip rendered alongside a message.
        When a message specifies tags, the client renders exactly those —
        no client-side synthesis or augmentation.
      properties:
        id:
          type: string
          description: Stable identifier (used for keying)
        label:
          type: string
          description: Display label
        icon:
          type: string
          description: Optional iconify icon id
        color:
          $ref: '#/components/schemas/MessageTagColor'
          description: Defaults to "muted" if omitted
        variant:
          $ref: '#/components/schemas/MessageTagVariant'
          description: Defaults to "subtle" if omitted
        type:
          type: string
          description: |
            Free-form classifier the server may use for future grouping or
            filtering. The client treats this as opaque metadata.
      required:
        - id
        - label
    PlaygroundMessageDisplay:
      type: string
      enum:
        - bubble
        - log
        - notice
        - card
      description: |
        Layout hint chosen by the server. When omitted, the client defaults
        from the role:
        - `log` → `log`
        - `system` (with compactSystemMessages enabled) → `notice`
        - everything else → `bubble`

        Layouts:
        - `bubble` — chat bubble with avatar, header, body, optional footer
          containing hierarchy + tags
        - `log` — one-liner: icon · hierarchy · body · tags · timestamp
        - `notice` — compact centered notice
        - `card` — vertical: hierarchy (top), body (middle), tags (bottom)
    AgentSpecNodeBase:
      type: object
      description: Base properties shared by all Agent Spec nodes
      properties:
        component_type:
          $ref: '#/components/schemas/AgentSpecNodeComponentType'
        name:
          type: string
          description: Node name (used as identifier in edges)
          example: process_input
        description:
          type: string
          description: Human-readable description
        inputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
          description: Input properties
        outputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
          description: Output properties
        metadata:
          type: object
          additionalProperties: true
          description: |
            Extension metadata. Includes FlowDrop-specific data for round-trip:
            - `flowdrop:position` — Node position `{x, y}` on the canvas
            - `flowdrop:dynamic` — Whether ports are dynamically configured
      required:
        - component_type
        - name
    AgentSpecRuntimeValidation:
      type: object
      description: Runtime validation result for an Agent Spec flow
      properties:
        valid:
          type: boolean
          description: Whether the flow is valid on the runtime
        errors:
          type: array
          items:
            type: string
          description: Validation errors from the runtime
      required:
        - valid
    AgentSpecRuntimeAgent:
      type: object
      description: Agent available on the runtime
      properties:
        name:
          type: string
          description: Agent name
        description:
          type: string
          description: Agent description
        inputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
        outputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
    AgentSpecRuntimeTool:
      type: object
      description: Tool available on the runtime
      properties:
        name:
          type: string
          description: Tool name
        description:
          type: string
          description: Tool description
        component_type:
          $ref: '#/components/schemas/AgentSpecToolComponentType'
        inputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
        outputs:
          type: array
          items:
            $ref: '#/components/schemas/AgentSpecProperty'
    AgentSpecRuntimeHealth:
      type: object
      description: Health status of the Agent Spec runtime
      properties:
        status:
          type: string
          example: healthy
        version:
          type: string
          example: 1.0.0
        runtime:
          type: string
          description: Runtime name (e.g., "wayflow", "pyagentspec")
          example: wayflow
  responses:
    BadRequest:
      description: Bad request - invalid parameters or request body
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error: Invalid request parameters
            code: VALIDATION_ERROR
            details:
              field: name
              message: Name is required
    Unauthorized:
      description: Unauthorized - authentication required
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error: Authentication required
            code: UNAUTHORIZED
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error: Resource not found
            code: NOT_FOUND
    ValidationError:
      description: Validation error - request data failed validation
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error: Validation failed
            code: VALIDATION_ERROR
            details:
              errors:
                - Node 'node-1' has invalid configuration
                - Edge 'edge-1' connects to non-existent node
    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error: Internal server error
            code: INTERNAL_ERROR
