Skip to content

Conversation

@aadamsx
Copy link

@aadamsx aadamsx commented Dec 27, 2025

Summary

Adds the ability to export Sim Studio workflows as standalone, self-contained Python services that can be deployed independently via Docker, Railway, or any container platform.

Features

Multi-Provider LLM Support

  • Anthropic: Claude 3/4 models (Opus, Sonnet, Haiku)
  • OpenAI: GPT-4, GPT-4o, o1, o3 models
  • Google: Gemini Pro, Gemini Flash models
  • Automatic provider detection from model name
  • Provider-specific API key environment variables

Supported Block Types

  • Start/Trigger blocks
  • Agent blocks (with multi-provider support)
  • Function blocks (JavaScript transpiled to Python)
  • Condition/Router blocks
  • API blocks (HTTP requests)
  • Loop blocks (for, forEach, while, doWhile)
  • Variables blocks
  • Response blocks

File Operations

Agents can perform file operations in two ways:

Option 1: Local File Tools (WORKSPACE_DIR)

Set the WORKSPACE_DIR environment variable to enable local file operations:

# In .env
WORKSPACE_DIR=./workspace

When enabled, agents automatically get access to these tools:

Tool Description
local_write_file Write text content to a file
local_write_bytes Write binary data (images, PDFs) as base64
local_append_file Append text to a file (creates if not exists)
local_read_file Read text content from a file
local_read_bytes Read binary data as base64
local_delete_file Delete a file
local_list_directory List files with metadata (size, modified time)

Enable Command Execution (opt-in for security):

# In .env
WORKSPACE_DIR=./workspace
ENABLE_COMMAND_EXECUTION=true

When enabled, agents also get:

Tool Description
local_execute_command Run commands like python script.py or node process.js

Shell operators (|, >, &&, etc.) are blocked for security.

File Size Limits:

# Default: 100MB. Set custom limit in bytes:
MAX_FILE_SIZE=52428800  # 50MB

All paths are sandboxed to WORKSPACE_DIR - agents cannot access files outside this directory. Path traversal attacks (../) and symlink escapes are blocked.

With Docker: The docker-compose.yml mounts ./output to the container workspace:

docker compose up -d
# Files written by agents appear in ./output/

Option 2: MCP Filesystem Tools

If your workflow uses MCP filesystem servers, those tools work as configured. MCP servers handle file operations on their own systems - paths and permissions are determined by the MCP server's configuration.

Using Both

You can use both options together. If WORKSPACE_DIR is set, agents will have access to both local file tools AND any MCP tools configured in the workflow. Tool descriptions help the LLM choose the appropriate tool for each operation.

Health Check with Workspace Status

The /health endpoint returns workspace configuration status:

{
  "status": "healthy",
  "workspace": {
    "enabled": true,
    "workspace_dir": "/app/workspace",
    "command_execution_enabled": false,
    "max_file_size": 104857600
  }
}

Export Validation

  • Pre-export validation for unsupported block types
  • Pre-export validation for unsupported providers
  • Clear error messages shown to users via notification system
  • Prevents silent failures with actionable feedback

Security

  • No eval(): All condition evaluation uses safe AST-based parsing
  • No shell=True: Commands executed without shell to prevent injection
  • File operations sandboxed to WORKSPACE_DIR
  • Shell operators rejected with clear error messages
  • Path traversal attacks blocked (no .. or symlink escapes)
  • File size limits (configurable, default 100MB)
  • Command execution is opt-in (disabled by default)

Production Features

  • FastAPI server with /execute, /health, /ready endpoints
  • Rate limiting (configurable, default 60 req/min)
  • Request size limits (configurable, default 10MB)
  • Automatic retry with exponential backoff
  • MCP tool support via official Python SDK
  • Docker and docker-compose configuration
  • Environment variable management (.env, .env.example)

Production Configuration

Environment Variable Default Description
HOST 0.0.0.0 Server bind address
PORT 8080 Server port
WORKSPACE_DIR (disabled) Enable local file tools with sandbox path
ENABLE_COMMAND_EXECUTION false Allow agents to execute commands
MAX_FILE_SIZE 104857600 (100MB) Maximum file size in bytes
WORKFLOW_PATH workflow.json Path to workflow definition
RATE_LIMIT_REQUESTS 60 Max requests per rate limit window
RATE_LIMIT_WINDOW 60 Rate limit window in seconds
MAX_REQUEST_SIZE 10485760 (10MB) Maximum HTTP request body size
LOG_LEVEL INFO Logging level

UI Integration

  • "Export as Service" context menu option
  • Single workflow export only (no bulk)
  • Error notifications via existing notification system
  • Uses ref pattern to avoid stale closure issues

Architecture

┌────────────────────────────────────────────────────────────────┐
│                    File Operations                              │
├────────────────────────────────────────────────────────────────┤
│                                                                 │
│  WORKSPACE_DIR set in .env?                                     │
│       │                                                         │
│       ├─ YES → Local tools auto-registered (7-8 tools):        │
│       │        • local_write_file (sandboxed)                   │
│       │        • local_write_bytes (binary/base64)              │
│       │        • local_append_file (sandboxed)                  │
│       │        • local_read_file (sandboxed)                    │
│       │        • local_read_bytes (binary/base64)               │
│       │        • local_delete_file (sandboxed)                  │
│       │        • local_list_directory (with metadata)           │
│       │        • local_execute_command (if ENABLE_COMMAND_      │
│       │          EXECUTION=true)                                │
│       │                                                         │
│       └─ NO  → Local tools disabled, returns helpful error:    │
│                "Set WORKSPACE_DIR or use MCP filesystem tools"  │
│                                                                 │
│  MCP tools in workflow? → Always available, hit external server │
│                                                                 │
│  Both enabled? → LLM picks based on tool descriptions           │
└────────────────────────────────────────────────────────────────┘

Files Changed

  • apps/sim/app/api/workflows/[id]/export-service/route.ts - API endpoint (refactored to 161 lines)
  • apps/sim/app/api/workflows/[id]/export-service/validate.ts - Workflow validation
  • apps/sim/app/api/workflows/[id]/export-service/transpile.ts - JS to Python transpilation
  • apps/sim/app/api/workflows/[id]/export-service/generate-zip.ts - ZIP generation
  • apps/sim/app/api/workflows/[id]/export-service/templates/ - 16 Python template files
  • apps/sim/app/api/workflows/[id]/export-service/route.test.ts - 13 unit tests
  • apps/sim/app/workspace/.../hooks/use-export-service.ts - React hook
  • apps/sim/app/workspace/.../context-menu/context-menu.tsx - UI menu
  • apps/sim/app/workspace/.../workflow-item/workflow-item.tsx - UI wiring
  • README.md - Updated with comprehensive export documentation

Testing

cd apps/sim && bun run vitest run "export-service"
# 13 tests passing

Usage

  1. Right-click workflow in sidebar
  2. Select "Export as Service"
  3. Extract ZIP and configure .env with API keys
  4. Optionally set WORKSPACE_DIR for local file operations
  5. Optionally set ENABLE_COMMAND_EXECUTION=true for command execution
  6. Run: docker compose up or uvicorn main:app
  7. Call: POST /execute with workflow inputs

@vercel
Copy link

vercel bot commented Dec 27, 2025

@aadamsx is attempting to deploy a commit to the Sim Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Dec 27, 2025

Greptile Summary

This PR adds workflow export as standalone Python/FastAPI services. The implementation includes pre-export validation for unsupported block types and providers, JavaScript-to-Python transpilation, and comprehensive ZIP generation with all necessary runtime files.

Key Changes:

  • API endpoint (route.ts) validates workflows, transpiles JS function blocks to Python, and generates deployable service ZIP with FastAPI server, executor, Docker config, and environment files
  • React hook (use-export-service.ts) properly uses refs to avoid stale closures and integrates with notification system
  • UI integration adds "Export as Service" to context menu for single workflow selection
  • 13 comprehensive tests cover authentication, validation, provider detection, and error handling

Architecture:

  • Follows established patterns: proper import aliases, hook structure with refs for stable dependencies, TSDoc documentation
  • Security-conscious: no eval(), AST-based condition parsing, sandboxed file operations in exported Python code
  • Good error handling with user-facing notifications for validation failures

Minor Observations:

  • The 2799-line route file is very large and contains embedded Python code as template strings, which is appropriate for this use case but makes the file substantial

Confidence Score: 4/5

  • This PR is safe to merge with minimal risk
  • Well-tested feature with comprehensive validation, proper error handling, and security measures. The code follows project patterns and includes 13 passing tests. The large route file is justified by embedded Python templates. Minor score reduction only due to the complexity and size of the implementation.
  • No files require special attention

Important Files Changed

Filename Overview
apps/sim/app/api/workflows/[id]/export-service/route.ts Adds API endpoint to export workflows as standalone Python/FastAPI services with validation, transpilation, and ZIP generation
apps/sim/app/workspace/[workspaceId]/w/hooks/use-export-service.ts React hook for exporting workflows with proper ref usage to avoid stale closures, error handling, and notification integration
apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/workflow-item/workflow-item.tsx Integrates export service hook with workflow item, wires up context menu handler for single workflow exports

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as WorkflowItem
    participant Hook as useExportService
    participant API as /api/workflows/[id]/export-service
    participant DB as Database
    participant Validator as Workflow Validator
    participant Transpiler as JS→Python Transpiler
    participant ZipGen as ZIP Generator

    User->>UI: Right-click workflow
    UI->>UI: Show context menu
    User->>UI: Click "Export as Service"
    UI->>Hook: handleExportService()
    Hook->>Hook: Check isExportingRef
    Hook->>Hook: setIsExporting(true)
    
    Hook->>API: GET /api/workflows/{id}/export-service
    API->>API: Authenticate user/API key
    API->>DB: Query workflow by ID
    DB-->>API: Return workflow data
    API->>API: Fetch workflow state & variables
    
    API->>Validator: validateWorkflowForExport(state)
    Validator->>Validator: Check block types
    Validator->>Validator: Check provider support
    
    alt Has unsupported blocks/providers
        Validator-->>API: Return validation errors
        API-->>Hook: 400 with error details
        Hook->>Hook: addNotification(error)
        Hook->>Hook: setIsExporting(false)
        Hook-->>User: Show error notification
    else Validation passes
        Validator-->>API: Valid workflow
        API->>Transpiler: preTranspileWorkflow(state)
        Transpiler->>Transpiler: Convert JS blocks to Python
        Transpiler-->>API: Transpiled workflow
        
        API->>ZipGen: Generate service ZIP
        ZipGen->>ZipGen: Create workflow.json
        ZipGen->>ZipGen: Create .env with API keys
        ZipGen->>ZipGen: Add Python executor files
        ZipGen->>ZipGen: Add Dockerfile & docker-compose
        ZipGen->>ZipGen: Add README.md
        ZipGen-->>API: ZIP buffer
        
        API-->>Hook: 200 with ZIP file
        Hook->>Hook: Create blob & download link
        Hook->>Hook: Trigger browser download
        Hook->>Hook: setIsExporting(false)
        Hook->>Hook: onSuccess?.()
        Hook-->>User: Download workflow-service.zip
    end
Loading

@waleedlatif1 waleedlatif1 deleted the branch simstudioai:staging December 27, 2025 05:25
@waleedlatif1 waleedlatif1 reopened this Dec 27, 2025
@aadamsx aadamsx force-pushed the feature/workflow-to-process branch from eeb6716 to 9140955 Compare December 27, 2025 18:47
aadamsx and others added 10 commits December 27, 2025 13:58
Adds the ability to export Sim Studio workflows as standalone, self-contained
Python services that can be deployed independently via Docker, Railway, or
any container platform.

## Features

### Multi-Provider LLM Support
- **Anthropic**: Claude 3/4 models (Opus, Sonnet, Haiku)
- **OpenAI**: GPT-4, GPT-4o, o1, o3 models
- **Google**: Gemini Pro, Gemini Flash models
- Automatic provider detection from model name
- Provider-specific API key environment variables

### Supported Block Types
- Start/Trigger blocks
- Agent blocks (with multi-provider support)
- Function blocks (JavaScript transpiled to Python)
- Condition/Router blocks
- API blocks (HTTP requests)
- Loop blocks (for, forEach, while, doWhile)
- Variables blocks
- Response blocks

### Export Validation
- Pre-export validation for unsupported block types
- Pre-export validation for unsupported providers
- Clear error messages shown to users before export fails
- Prevents silent failures with actionable feedback

### Production Features
- FastAPI server with /execute, /health, /ready endpoints
- Rate limiting (configurable, default 60 req/min)
- Request size limits (configurable, default 10MB)
- Automatic retry with exponential backoff
- MCP tool support via official Python SDK
- File operation sandboxing (WORKSPACE_DIR)
- Docker and docker-compose configuration
- Environment variable management (.env, .env.example)

### UI Integration
- "Export as Service" context menu option
- Single workflow export only (no bulk)
- User-friendly error alerts for validation failures

## Files Changed

- `apps/sim/app/api/workflows/[id]/export-service/route.ts` - API endpoint
- `apps/sim/app/api/workflows/[id]/export-service/route.test.ts` - 13 unit tests
- `apps/sim/app/workspace/.../hooks/use-export-service.ts` - React hook
- `apps/sim/app/workspace/.../context-menu/context-menu.tsx` - UI menu
- `apps/sim/app/workspace/.../workflow-item/workflow-item.tsx` - UI wiring

## Testing

```bash
cd apps/sim && bun run vitest run "export-service"
# 13 tests passing
```

## Usage

1. Right-click workflow in sidebar
2. Select "Export as Service"
3. Extract ZIP and configure .env with API keys
4. Run: `docker compose up` or `uvicorn main:app`
5. Call: `POST /execute` with workflow inputs
- Replace 'any' types with proper interfaces (WorkflowBlock, WorkflowState, ExportWorkflowState, WorkflowVariable)
- Improve transpiler regex pattern to explicitly handle string and numeric bracket notation
- Add documentation for regex limitations with nested bracket access
- Use nullish coalescing (??) instead of logical OR (||) for safer defaults
Use the existing useNotificationStore to show error messages instead of
blocking browser alert(). Notifications appear in the bottom-right corner
and can be dismissed by the user.
- Replace all eval() with safe AST-based expression evaluation
  - Loop condition evaluation now uses _safe_eval_condition()
  - Condition handler uses _safe_eval_with_context() for variable access
  - Only allows safe operations: comparisons, boolean ops, len/str/int/bool

- Remove shell=True from execute_command to prevent command injection
  - Shell operators (|, >, <, &&, ;, $) are now rejected with clear error
  - Commands are parsed with shlex and executed without shell

- Fix model detection regex for o1-/o3- patterns
  - Use word boundary to avoid matching o10, o11, etc.
Replace isExporting state in dependency array with useRef to prevent
stale closure issues per hook best practices.
- Move Python templates from embedded strings to templates/ directory (16 files)
- Extract validation logic to validate.ts (122 lines)
- Extract transpilation logic to transpile.ts (153 lines)
- Extract ZIP generation to generate-zip.ts (229 lines)
- Reduce route.ts from 2799 to 161 lines (94% reduction)
- Fix logger import paths to use @sim/logger
- All 13 tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Native file tools (write, read, list) now require WORKSPACE_DIR to be set
- If WORKSPACE_DIR not set, tools return helpful error directing to MCP tools
- Agent handler auto-registers local_write_file, local_read_file, local_list_directory
  when WORKSPACE_DIR is configured
- Updated docker-compose.yml to mount ./output volume for container workspace
- Updated .env template with WORKSPACE_DIR documentation
- Updated README with comprehensive file operations documentation

This allows users to choose between:
1. Local file tools (set WORKSPACE_DIR) - sandboxed to workspace directory
2. MCP filesystem tools - handled by external MCP servers
3. Both together - LLM chooses appropriate tool based on descriptions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Quick start guide with Docker and direct execution
- Complete exported files reference table
- Multi-provider LLM support (Anthropic, OpenAI, Google)
- All supported block types with descriptions
- File operations: WORKSPACE_DIR local tools vs MCP tools
- API endpoints documentation (/execute, /health, /ready)
- Docker deployment instructions
- Production configuration environment variables
- Security measures (no eval, no shell, sandboxing, etc.)
- MCP tool support details
- Export validation and error handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…deletion, append, and command execution

- Add write_bytes/read_bytes for binary files (images, PDFs) via base64
- Add append_file for log/incremental writes
- Add delete_file for cleanup operations
- Add file size limits (MAX_FILE_SIZE, default 100MB)
- Add command execution opt-in (ENABLE_COMMAND_EXECUTION)
- Enhance list_directory with metadata (size, modified, extension)
- Add workspace status to /health endpoint
- Update .env template and README with comprehensive documentation

All 7-8 tools (8 if command execution enabled) auto-register when WORKSPACE_DIR set.
Security: Command execution opt-in, file size limits, existing sandboxing maintained.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds support for all Sim Studio LLM providers in exported services:

Hosted Providers:
- Anthropic (claude-*)
- OpenAI (gpt-*, o1-*, o3-*, o4-*)
- Google (gemini-*)
- DeepSeek (deepseek-*)
- xAI (grok-*)
- Cerebras (cerebras/*)
- Groq (groq/*)
- Mistral (mistral-*, magistral-*, codestral-*, etc.)
- OpenRouter (openrouter/*)
- Azure OpenAI (azure/*)

Self-Hosted Providers:
- Vertex AI (vertex/*)
- Ollama (ollama/*)
- vLLM (vllm/*)

Implementation:
- Generic OpenAI-compatible handler for most providers
- Azure OpenAI handler with endpoint/version config
- Vertex AI uses Google Gemini SDK
- Auto-detection from model name prefixes
- Unknown models default to OpenAI (most compatible)

Updated files:
- agent.py: Multi-provider routing with base URL configs
- validate.ts: Accept all 13 providers
- generate-zip.ts: .env template with all API keys
- route.test.ts: Provider detection tests (22 tests passing)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@aadamsx aadamsx force-pushed the feature/workflow-to-process branch from b4e8480 to 7817c52 Compare December 27, 2025 19:58
aadamsx and others added 2 commits December 27, 2025 20:55
Use process.cwd() relative path instead of __dirname which doesn't
work correctly with Next.js turbopack compilation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This guide documents how to:
- Create workflows programmatically via direct database operations
- Configure all supported block types (start, agent, api, function, response, etc.)
- Set up MCP tools and local file operations
- Export workflows to standalone Python services
- Run and test exported services

Includes SQL templates, block configuration examples, and troubleshooting tips.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants