Skip to main content

Creating Custom Operators

This document will guide you through creating and managing custom operators on the GeniSpace platform, including both manual creation and OpenAPI document import methods.

Custom Operators vs System Operators

Before creating custom operators, let's understand the differences between custom and system operators:

FeatureCustom OperatorsSystem Operators
CreatorCreated by usersCreated by platform administrators
Configuration PermissionsFully configurable and customizableOnly user-facing portions configurable; system configuration is hidden
Maintenance ResponsibilityMaintained by the userMaintained and updated by the platform
Ease of UseHigh barrier; requires technical configurationLow barrier; enable and use immediately
Customization LevelFully customizableLimited customization
Sharing ScopeIndividual or within a teamAvailable to all platform users

Recommended Use Cases:

  • Choose System Operators: If the platform already has an operator that meets your needs, prioritize using system operators
  • Choose Custom Operators: When you need specialized functionality, integration with private services, or when existing system operators cannot meet your requirements

Creation Methods Overview

GeniSpace provides multiple ways to create custom operators:

  1. Manual Creation - Build an operator from scratch
  2. OpenAPI Import - Quickly generate operators from OpenAPI documents
  3. Docker Container - Create operators based on containerized applications

Manual Operator Creation

Step 1: Basic Information Configuration

First, configure the basic information for the operator:

{
"name": "User Management Tool",
"identifier": "user-management",
"description": "Provides CRUD operations for user information",
"category": "api",
"executionType": "api",
"version": "1.0.0",
"tags": ["user", "management", "API"]
}

Field Descriptions:

  • name: Operator display name
  • identifier: Unique identifier, can only contain lowercase letters, numbers, and hyphens
  • description: Operator function description
  • category: Operator category (api, data-source, transform, etc.)
  • executionType: Execution type (api, worker, mcp, container)
  • version: Version number
  • tags: Tag list for search and categorization

Step 2: Runtime Configuration (User Configuration)

Custom operators use a single-layer configuration structure where all configuration is fully controlled by the user. Configure the global runtime parameters for the operator:

{
"configuration": {
"schema": {
"type": "object",
"properties": {
"serverUrl": {
"type": "string",
"title": "Server URL",
"required": true,
"description": "Base URL of the API server"
},
"apiKey": {
"type": "string",
"title": "API Key",
"sensitive": true,
"description": "Key for accessing the API"
},
"timeout": {
"type": "number",
"title": "Global Timeout",
"default": 30000,
"description": "Request timeout in milliseconds"
},
"headers": {
"type": "array",
"title": "Global Headers",
"items": {
"type": "object",
"properties": {
"key": {"type": "string"},
"value": {"type": "string"}
}
}
}
}
},
"values": {
"serverUrl": "https://api.example.com",
"apiKey": "your-api-key-here",
"timeout": 30000,
"headers": [
{"key": "Content-Type", "value": "application/json"}
]
}
}
}
caution

Unlike system operators, all configuration for custom operators (including sensitive information) must be configured and managed by the user. It is recommended to use sensitive: true to mark sensitive fields.

Step 3: Adding Methods

Each operator can contain multiple methods, with each method representing a specific function:

Method Basic Information

{
"name": "Get User Info",
"identifier": "get-user",
"description": "Get detailed user information by user ID",
"isDefault": true,
"order": 1,
"status": "ACTIVE"
}

Input Schema

Define the input parameters accepted by the method:

{
"inputSchema": {
"type": "object",
"required": ["userId"],
"properties": {
"userId": {
"type": "string",
"title": "User ID",
"description": "The user ID to query",
"isPort": true
},
"includeProfile": {
"type": "boolean",
"title": "Include Details",
"description": "Whether to include detailed user profile",
"default": false
}
}
}
}

Output Schema

Define the output results produced by the method:

{
"outputSchema": {
"type": "object",
"properties": {
"user": {
"type": "object",
"title": "User Information",
"properties": {
"id": {"type": "string", "title": "User ID"},
"name": {"type": "string", "title": "Username"},
"email": {"type": "string", "title": "Email"},
"profile": {
"type": "object",
"title": "Profile Details",
"properties": {
"avatar": {"type": "string", "title": "Avatar"},
"bio": {"type": "string", "title": "Bio"}
}
}
}
},
"metadata": {
"type": "object",
"title": "Metadata",
"properties": {
"timestamp": {"type": "string", "title": "Query Time"},
"source": {"type": "string", "title": "Data Source"}
}
}
}
}
}

Method Configuration

Define method-specific configuration parameters:

{
"configuration": {
"schema": {
"type": "object",
"properties": {
"method": {
"type": "string",
"title": "Request Method",
"enum": ["GET", "POST"],
"default": "GET",
"required": true
},
"endpoint": {
"type": "string",
"title": "Endpoint Path",
"description": "Endpoint path relative to the server URL",
"required": true
},
"caching": {
"type": "object",
"title": "Cache Configuration",
"properties": {
"enabled": {
"type": "boolean",
"title": "Enable Caching",
"default": false
},
"ttlSeconds": {
"type": "number",
"title": "Cache Duration",
"default": 3600
}
}
}
}
},
"values": {
"method": "GET",
"endpoint": "/api/users/{userId}",
"caching": {
"enabled": true,
"ttlSeconds": 1800
}
}
}
}

Importing from OpenAPI

Supported Formats

GeniSpace supports importing operators from the following OpenAPI document formats:

  • OpenAPI 3.0 (JSON/YAML)
  • Swagger 2.0 (JSON/YAML)

Import Methods

1. URL Import

Import OpenAPI documents directly from a URL:

https://api.example.com/openapi.json
https://api.example.com/swagger.yaml

2. File Upload

Upload local OpenAPI document files:

  • .json files
  • .yaml or .yml files

Auto-Generated Content

When importing from an OpenAPI document, the system automatically generates:

Operator Basic Information

{
"name": "User API", // from info.title
"description": "User management API", // from info.description
"identifier": "user-api", // auto-generated
"version": "1.0.0" // from info.version
}

Server Configuration

{
"configuration": {
"values": {
"serverUrl": "https://api.example.com" // from servers[0].url
}
}
}

Method Generation

Each API endpoint generates a corresponding method:

# OpenAPI definition
paths:
/users/{id}:
get:
summary: "Get user info"
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: "User information"
content:
application/json:
schema:
type: object
properties:
id:
type: string
name:
type: string

Generated method:

{
"name": "Get user info",
"identifier": "get-users-id",
"inputSchema": {
"type": "object",
"required": ["id"],
"properties": {
"id": {
"type": "string",
"title": "User ID",
"isPort": true
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"result": {
"type": "object",
"properties": {
"id": {"type": "string"},
"name": {"type": "string"}
}
}
}
},
"configuration": {
"values": {
"method": "GET",
"endpoint": "/users/{id}"
}
}
}

Post-Import Adjustments

After import is complete, you can further adjust:

  1. Modify Operator Information: Adjust the name, description, category, etc.
  2. Optimize Schemas: Refine input/output data structure definitions
  3. Add Validation Rules: Add validation constraints to parameters
  4. Configure Caching Policies: Set appropriate caching rules
  5. Set Default Values: Provide default values for optional parameters

Configuration Security

Sensitive Information Handling

Custom operators require users to manage all configuration themselves, including sensitive information. The following security practices are recommended:

1. Mark Sensitive Fields

{
"apiKey": {
"type": "string",
"title": "API Key",
"sensitive": true,
"description": "Key for authentication"
},
"password": {
"type": "string",
"title": "Password",
"sensitive": true,
"format": "password"
}
}

2. Use Environment Variables

{
"configuration": {
"values": {
"apiKey": "${API_KEY}",
"serverUrl": "${SERVER_URL:-https://api.example.com}"
}
}
}

3. Configuration Validation

{
"apiKey": {
"type": "string",
"pattern": "^[A-Za-z0-9]{32}$",
"description": "32-character alphanumeric string"
},
"serverUrl": {
"type": "string",
"format": "uri",
"pattern": "^https://.*"
}
}

Access Control

  • Team Sharing: Custom operators can be shared with team members
  • Permission Management: Set different editing permissions for different members
  • Usage Restrictions: Operator usage scope and frequency can be limited

Docker Container Operators

Basic Configuration

{
"executionType": "container",
"systemConfiguration": {
"schema": {
"type": "container",
"properties": {
"image": {
"type": "string",
"title": "Container Image",
"required": true
},
"command": {
"type": "string",
"title": "Execution Command"
},
"environment": {
"type": "object",
"title": "Environment Variables"
},
"resources": {
"type": "object",
"title": "Resource Limits",
"properties": {
"memory": {"type": "string", "default": "512Mi"},
"cpu": {"type": "string", "default": "0.5"}
}
}
}
},
"values": {
"image": "my-app:latest",
"command": "python app.py",
"environment": {
"API_KEY": "secret"
},
"resources": {
"memory": "512Mi",
"cpu": "0.5"
}
}
}
}

Container Requirements

Containerized operators must meet the following requirements:

  1. Input/Output Specification: Receive JSON-formatted input via standard input, and return JSON-formatted results via standard output
  2. Error Handling: Use appropriate exit codes to indicate execution status
  3. Log Output: Send logs to standard error stream
  4. Resource Management: Use memory and CPU resources responsibly

Example Container Code

#!/usr/bin/env python3
import json
import sys

def main():
try:
# Read parameters from standard input
input_data = json.load(sys.stdin)

# Process business logic
result = process_data(input_data)

# Output result to standard output
json.dump(result, sys.stdout)
sys.exit(0)

except Exception as e:
# Output error to standard error
print(f"Error: {str(e)}", file=sys.stderr)
sys.exit(1)

def process_data(data):
# Actual business processing logic
return {
"status": "success",
"data": data,
"timestamp": "2024-01-01T00:00:00Z"
}

if __name__ == "__main__":
main()

Testing and Debugging

1. Configuration Validation

Before saving the operator, the system automatically validates:

  • JSON Schema format correctness
  • Required field completeness
  • Data type consistency
  • Identifier uniqueness

2. Method Testing

You can test methods directly in the operator editing interface:

{
"testInput": {
"userId": "12345",
"includeProfile": true
},
"expectedOutput": {
"user": {
"id": "12345",
"name": "John Doe",
"email": "john@example.com"
}
}
}

3. Workflow Integration Testing

Add the operator to a test workflow and verify:

  • Input/output connection correctness
  • Proper data flow
  • Error handling mechanisms
  • Performance behavior

Version Management

Version Number Convention

Semantic versioning is recommended:

  • Major Version: Incompatible API changes
  • Minor Version: Backward-compatible feature additions
  • Patch Version: Backward-compatible bug fixes

Example: 1.2.3

Update Strategy

  1. Backward-Compatible Updates: Bug fixes, performance optimizations
  2. Feature Updates: New methods, expanded configuration
  3. Breaking Updates: Modified existing interfaces, removed features

Migration Guide

When releasing breaking updates, provide:

  1. Change Description: Detailed explanation of modifications
  2. Migration Steps: Guide users through the upgrade process
  3. Compatibility Notes: Describe the scope of impact
  4. Rollback Plan: Provide a downgrade plan

Best Practices

1. Design Principles

  • Single Responsibility: Each operator should focus on a specific domain
  • Interface Stability: Avoid frequent breaking changes to public interfaces
  • Error Friendliness: Provide clear error messages
  • Complete Documentation: Write detailed usage instructions

2. Performance Optimization

  • Proper Caching: Enable caching for appropriate operations
  • Timeout Settings: Set reasonable timeout durations
  • Resource Limits: Avoid excessive resource consumption
  • Concurrency Control: Handle high-concurrency scenarios

3. Security Considerations

  • Input Validation: Strictly validate all input parameters
  • Access Control: Implement appropriate access controls
  • Sensitive Information: Handle sensitive data properly
  • Audit Logging: Record important operations

4. Maintenance Management

  • Monitoring and Alerts: Set up monitoring for key metrics
  • Logging: Record detailed execution logs
  • Regular Updates: Fix issues and security vulnerabilities promptly
  • User Feedback: Collect and process user feedback

5. Selection Guide

When to Choose Custom Operators

  • Private Service Integration: Need to connect to internal or private API services
  • Specialized Business Logic: Need to implement specific business processing logic
  • Customization Requirements: Existing system operators cannot meet specialized needs
  • Data Processing: Need specialized data transformation or processing capabilities
  • Third-Party Integration: Integration with specific third-party services or tools

When to Choose System Operators

  • Common Services: Using common third-party services (WeChat, email, etc.)
  • Standard Functionality: Need standardized feature implementations
  • Quick Start: Want to start using quickly without complex configuration
  • Maintenance Cost: Want to reduce maintenance workload
  • Best Practices: Want to use proven implementation approaches