Skip to content

vince-hz/script-runner-proxy

Repository files navigation

Script Runner Proxy

OOMOL task blocks for executing and managing scripts via the script-runner HTTP API. This project provides visual workflow integration for local script execution with support for both synchronous and asynchronous execution modes.

Overview

This package provides 5 task blocks that map to script-runner's REST API endpoints, enabling you to:

  • Execute scripts asynchronously and track via job ID
  • Execute scripts synchronously and get immediate results
  • Monitor job status and progress
  • Retrieve paginated logs (stdout/stderr)
  • Cancel running or queued jobs

Prerequisites

You need a running instance of script-runner with configured scripts. Follow the script-runner setup instructions to:

  1. Install script-runner: npm install -g @vince-hz/script-runner
  2. Create config.json and scripts.json configuration files
  3. Start the service: script-runner start

By default, script-runner runs on http://localhost:3000.

Task Blocks

1. Run Script (Async)

Execute a script asynchronously and return a job ID for tracking.

Inputs:

  • script_id (string, required) - Script identifier from scripts.json
  • args (array of strings, optional) - Arguments to pass to the script
  • script_runner_url (string, default: "http://localhost:3000") - Base URL of script-runner

Outputs:

  • job_id (string) - Job ID for tracking execution progress

Usage: Returns immediately with a job_id. Use this with get-job-status and get-job-logs blocks to monitor execution and retrieve results.

2. Run Script (Sync)

Execute a script synchronously and wait for completion.

Inputs:

  • script_id (string, required) - Script identifier from scripts.json
  • args (array of strings, optional) - Arguments to pass to the script
  • script_runner_url (string, default: "http://localhost:3000") - Base URL of script-runner

Outputs:

  • stdout (string) - Standard output from script execution
  • stderr (string) - Standard error from script execution
  • exit_code (number) - Exit code from script execution
  • status (string) - Job status

Usage: Blocks until script completes and returns all results immediately. Best for quick scripts where you need immediate results.

3. Get Job Status

Query the status and metadata of an async job.

Inputs:

  • job_id (string, required) - Job identifier from async execution
  • script_runner_url (string, default: "http://localhost:3000")

Outputs:

  • status (string) - Job status: queued, running, completed, failed, or cancelled
  • exit_code (number, nullable) - Exit code (available when completed or failed)
  • stdout_preview (string) - Preview of stdout logs
  • stderr_preview (string) - Preview of stderr logs

4. Get Job Logs

Retrieve paginated logs from an async job.

Inputs:

  • job_id (string, required) - Job identifier
  • stream (enum: stdout/stderr, default: stdout) - Log stream to retrieve
  • offset (number, default: 0) - Starting line number
  • limit (number, default: 100) - Maximum lines to retrieve
  • script_runner_url (string, default: "http://localhost:3000")

Outputs:

  • logs (array of strings) - Log lines
  • total_lines (number) - Total available lines in stream

Usage: Use offset and limit for pagination. Example: retrieve lines 100-199 with offset: 100, limit: 100.

5. Cancel Job

Terminate a running or queued async job.

Inputs:

  • job_id (string, required) - Job identifier to cancel
  • script_runner_url (string, default: "http://localhost:3000")

Outputs:

  • success (boolean) - Whether cancellation succeeded
  • message (string) - Result message

Notes:

  • Queued jobs are removed immediately
  • Running jobs receive SIGTERM signal
  • Completed jobs cannot be cancelled

Workflow Patterns

Async Execution with Monitoring

nodes:
  # 1. Start async execution
  - node_id: run#1
    task: self::run-script-async
    inputs_from:
      - handle: script_id
        value: "my-script"

  # 2. Check status
  - node_id: status#1
    task: self::get-job-status
    inputs_from:
      - handle: job_id
        from_node:
          - node_id: run#1
            output_handle: job_id

  # 3. Retrieve full logs
  - node_id: logs#1
    task: self::get-job-logs
    inputs_from:
      - handle: job_id
        from_node:
          - node_id: run#1
            output_handle: job_id
      - handle: stream
        value: stdout

Sync Execution (Simple)

nodes:
  - node_id: run-sync#1
    task: self::run-script-sync
    inputs_from:
      - handle: script_id
        value: "my-script"
      - handle: args
        value: ["arg1", "arg2"]

The outputs (stdout, stderr, exit_code, status) are available immediately after execution completes.

When to Use Async vs Sync

Use Async (run-script-async) when:

  • Script execution takes more than a few seconds
  • You need to monitor progress or retrieve logs incrementally
  • You want the ability to cancel long-running tasks
  • You're running multiple scripts in parallel

Use Sync (run-script-sync) when:

  • Script execution is quick (< 5 seconds)
  • You need immediate results in a simple workflow
  • You don't need progress monitoring
  • You want simpler workflow design

Error Handling

All task blocks raise exceptions with descriptive messages for:

  • Connection failures (script-runner not running)
  • HTTP errors (invalid script_id, job_id not found)
  • Timeout errors (request exceeds timeout)
  • Invalid responses (malformed JSON, missing fields)

Error messages include status codes and response details to aid debugging.

Example Test Flow

See flows/flow-1/flow.oo.yaml for a comprehensive test flow demonstrating:

  • Async execution with status polling and log retrieval
  • Sync execution with immediate results
  • Both stdout and stderr log streams

Configuration

All task blocks accept script_runner_url parameter. You can:

  • Use the default http://localhost:3000 for local development
  • Override per-workflow for different script-runner instances
  • Use http://host.docker.internal:8080 when running in Docker to access host machine
  • Configure script-runner to run on different ports via its config.json

Development

Installation

poetry add requests
poetry install --no-root

Testing

  1. Start script-runner with test scripts:

    # Create scripts.json with test scripts
    script-runner start
  2. Update flow.oo.yaml with your script IDs

  3. Run the test flow using OOMOL's execution tools

Architecture

Design Decisions

Why separate blocks for async and sync?

  • Clear type contracts: Each block has specific, non-nullable outputs
  • Better composability: Outputs always match what downstream blocks expect
  • Clearer intent: Block name indicates behavior
  • No conditional logic: Users know exactly what they're getting
  • Follows OOMOL patterns: Each block does one thing well

Alternative considered: Single block with mode parameter was rejected because:

  • Outputs are mutually exclusive (either job_id OR results, never both)
  • Connection issues due to nullable outputs
  • Confusing UX with conditionally populated outputs

API Reference

This project implements the following script-runner endpoints:

  • POST /run - Execute scripts (sync/async)
  • GET /jobs/:jobId - Query job status
  • GET /jobs/:jobId/logs - Retrieve logs with pagination
  • POST /jobs/:jobId/cancel - Cancel jobs

For complete script-runner API documentation, see script-runner repository.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages