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:
| Feature | Custom Operators | System Operators |
|---|---|---|
| Creator | Created by users | Created by platform administrators |
| Configuration Permissions | Fully configurable and customizable | Only user-facing portions configurable; system configuration is hidden |
| Maintenance Responsibility | Maintained by the user | Maintained and updated by the platform |
| Ease of Use | High barrier; requires technical configuration | Low barrier; enable and use immediately |
| Customization Level | Fully customizable | Limited customization |
| Sharing Scope | Individual or within a team | Available 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:
- Manual Creation - Build an operator from scratch
- OpenAPI Import - Quickly generate operators from OpenAPI documents
- 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 nameidentifier: Unique identifier, can only contain lowercase letters, numbers, and hyphensdescription: Operator function descriptioncategory: Operator category (api, data-source, transform, etc.)executionType: Execution type (api, worker, mcp, container)version: Version numbertags: 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"}
]
}
}
}
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:
.jsonfiles.yamlor.ymlfiles
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:
- Modify Operator Information: Adjust the name, description, category, etc.
- Optimize Schemas: Refine input/output data structure definitions
- Add Validation Rules: Add validation constraints to parameters
- Configure Caching Policies: Set appropriate caching rules
- 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:
- Input/Output Specification: Receive JSON-formatted input via standard input, and return JSON-formatted results via standard output
- Error Handling: Use appropriate exit codes to indicate execution status
- Log Output: Send logs to standard error stream
- 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
- Backward-Compatible Updates: Bug fixes, performance optimizations
- Feature Updates: New methods, expanded configuration
- Breaking Updates: Modified existing interfaces, removed features
Migration Guide
When releasing breaking updates, provide:
- Change Description: Detailed explanation of modifications
- Migration Steps: Guide users through the upgrade process
- Compatibility Notes: Describe the scope of impact
- 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
Related Documentation
- System Operators - Learn about system operator concepts and usage
- Operator Overview - Learn about basic operator concepts and types
- Operator Configuration Specification - Detailed configuration structure documentation
- OpenAPI Support - Learn how to import operators from OpenAPI documents
- Workflow Integration - Using operators in workflows