Skip to content

Repository files navigation

Omni Tool Runtime

Portable, cloud-agnostic execution runtime for OmniBioAI tools


Overview

omnibioai-tool-runtime is a minimal, deterministic execution runtime used by OmniBioAI’s Tool Execution Service (TES) to run individual tools across multiple execution backends, including:

  • Local Docker execution
  • AWS Batch
  • Azure Batch
  • GCP Batch (gs:// results upload)
  • Kubernetes Jobs
  • Slurm / HPC via TES adapters

The runtime provides a strict execution contract so that:

  • TES adapters stay thin and backend-specific
  • Tool containers remain portable and backend-agnostic
  • Results are uploaded consistently (S3 / Azure Blob / future backends)

This mirrors the design philosophy used throughout OmniBioAI: separate orchestration from execution, and execution from logic.


What This Runtime Is (and Is Not)

✅ This runtime is

  • A containerized tool launcher

  • Responsible for:

    • Reading tool inputs from environment variables
    • Executing tool logic
    • Writing results.json
    • Uploading results to cloud storage
  • Cloud-agnostic (AWS / Azure supported today)

❌ This runtime is not

  • A workflow engine
  • A scheduler
  • An LLM executor
  • A UI layer

Those responsibilities live elsewhere in OmniBioAI.


Execution Contract (Critical)

All tools executed via omnibioai-tool-runtime must follow this contract.

Environment Variables (Injected by TES Adapter)

Variable Description
TOOL_ID Tool identifier (echo_test, blastn, etc.)
RUN_ID Unique run ID (generated by adapter)
INPUTS_JSON JSON-encoded tool inputs
RESOURCES_JSON JSON-encoded resource request
S3_RESULT_URI (AWS Batch) S3 URI to upload results
RESULT_URI (Azure Batch) azureblob:// URI to upload results

Only one of S3_RESULT_URI or RESULT_URI is expected per run.


Repository Structure

omnibioai-tool-runtime/
├── Dockerfile
├── README.md
├── pyproject.toml
├── omni_tool_runtime/
│   ├── __init__.py
│   ├── contract.py            # ToolContract + read_contract_from_env() —
│   │                          # the code implementing "Execution Contract" below
│   ├── run.py                 # Generic entrypoint: resolves TOOL_ID ->
│   │                          # tools.{tool_id}.run and calls its main()
│   ├── result_uri.py          # URI parsing & dispatch
│   ├── upload_result.py       # Unified upload logic
│   └── uploaders/
│       ├── s3_uploader.py
│       └── azureblob_uploader.py
├── tools/
│   ├── echo_test/             # Minimal reference implementation — see below
│   │   ├── __init__.py
│   │   └── run.py
│   ├── generic_sif_runner/    # The real, production tool — embedded in every
│   │   └── run.py             # ECR/ACR/GCR image (see omnibioai-tes's README)
│   └── workflow_runner/
│       └── run.py
└── tests/

Testing

cd ~/Desktop/machine/omnibioai-tool-runtime
pytest tests/ -v --cov=.

# Coverage figures from earlier dated runs are historical snapshots; run the
# command above to measure the current checkout.
# Covers: upload_result, S3 uploader, Azure uploader,
#         echo_test/generic_sif_runner/workflow_runner tools, run lifecycle

Example Tool: echo_test

This is a minimal reference implementation — small enough to read end-to-end as a template for a new tool. The real, production tool embedded in every ECR/ACR/GCR image is tools/generic_sif_runner/ (see omnibioai-tes's README); a third, tools/workflow_runner/, also ships here.

Behavior

  • Reads INPUTS_JSON
  • Echoes a value
  • Writes results.json
  • Uploads results to configured storage backend

Minimal tool implementation

# tools/echo_test/run.py
import json
import os
from omni_tool_runtime.upload_result import upload_result

def main():
    tool_id = os.environ["TOOL_ID"]
    run_id = os.environ["RUN_ID"]
    inputs = json.loads(os.environ.get("INPUTS_JSON", "{}"))

    text = inputs.get("text", "")

    result = {
        "ok": True,
        "tool_id": tool_id,
        "run_id": run_id,
        "results": {"echo": text},
    }

    upload_result(result)

if __name__ == "__main__":
    main()

How Results Upload Works

upload_result() automatically detects the backend:

Backend URI Example
AWS s3://bucket/prefix/run_id/results.json
Azure azureblob://account/container/path/results.json
GCP gs://bucket/prefix/run_id/results.json (via google.cloud.storage)

The runtime:

  1. Serializes result as JSON
  2. Uploads to correct backend
  3. Prints result to stdout (for debugging)

Adapters never upload results themselves.


Building the Docker Image

From repository root:

# Build from ecosystem root (required — COPY needs omnibioai-tool-runtime/)
cd ~/Desktop/machine
docker build \
  -t ghcr.io/omnibioai/omnibioai-tool-runtime:latest \
  -f omnibioai-tool-runtime/Dockerfile \
  .

docker push ghcr.io/omnibioai/omnibioai-tool-runtime:latest

Verify:

docker images | grep omnibioai-tool-runtime

Running a Tool Locally (No Cloud)

docker run --rm \
  -e TOOL_ID=echo_test \
  -e RUN_ID=local-test-1 \
  -e INPUTS_JSON='{"text":"hello world"}' \
  -e RESOURCES_JSON='{}' \
  ghcr.io/omnibioai/omnibioai-tool-runtime:latest

Expected:

  • JSON output printed to stdout
  • No upload attempted if no result URI is provided

AWS Batch Usage

Job Definition

  • Image: ghcr.io/omnibioai/omnibioai-tool-runtime:latest
  • Command override:
["python", "-m", "tools.echo_test.run"]

Injected Environment

  • S3_RESULT_URI provided by AwsBatchAdapter
  • IAM Role handles S3 auth

Azure Batch Usage

Task Settings

  • Image: ghcr.io/omnibioai/omnibioai-tool-runtime:latest
  • Command:
python -m tools.echo_test.run

Injected Environment

  • RESULT_URI=azureblob://...
  • Managed Identity handles Blob auth

Pushing the Image

Docker Hub

docker push ghcr.io/omnibioai/omnibioai-tool-runtime:latest

Azure Container Registry

az acr login --name YOUR_ACR
docker tag ghcr.io/omnibioai/omnibioai-tool-runtime:latest YOUR_ACR.azurecr.io/omnibioai-tool-runtime:latest
docker push YOUR_ACR.azurecr.io/omnibioai-tool-runtime:latest

Adding a New Tool

Step 1: Create tool folder

mkdir tools/my_new_tool
touch tools/my_new_tool/__init__.py
touch tools/my_new_tool/run.py

Step 2: Implement run.py

Rules:

  • Must read env vars
  • Must write result via upload_result()
  • Must be deterministic

Step 3: Register tool in adapter config

AWS Batch

job_definition_map:
  my_new_tool: "omnibioai-my-new-tool:1"

Azure Batch

tools:
  my_new_tool:
    image: "ghcr.io/omnibioai/omnibioai-tool-runtime:latest"
    command: ["python", "-m", "tools.my_new_tool.run"]

Current State

Implemented

  • Unified runtime image embedded in all tool Docker images
  • AWS Batch support (S3 result upload)
  • Azure Batch support (Azure Blob result upload)
  • GCP Batch support (GCS result upload)
  • Kubernetes Job support — the same image runs unmodified as a K8s Job's container; no Kubernetes-specific code lives in this repo
  • Deterministic execution contract
  • Reference echo_test tool, plus the production generic_sif_runner and workflow_runner tools
  • 99% test coverage

Intentionally not included (by design)

  • No workflow orchestration
  • No retry logic
  • No state machine
  • No scheduling policy

The items above describe implemented runtime behavior and intentional boundaries. Backend availability, tool identity, and scheduler policy are owned by TES adapters and structured configuration, not by this runtime README.


Design Philosophy (Important)

This runtime is intentionally boring.

That’s a feature.

  • No magic
  • No backend assumptions
  • No hidden orchestration
  • One job → one tool → one result

Everything complex belongs above this layer.


Related Services

Service Role
omnibioai-tes Injects env vars and submits jobs using this runtime
omnibioai-tool-images Embeds this runtime in every tool Docker image
omnibioai-studio Orchestrates execution backends that run this runtime

Authoritative Sources

The execution contract is implemented in omni_tool_runtime/contract.py, run.py, result_uri.py, and upload_result.py. Backend-specific uploaders are under omni_tool_runtime/uploaders/; the reference and embedded tools are under tools/. TES configuration determines which tool image and backend are selected. This repository does not define the canonical TES tool catalog.


Final Note

If this runtime feels similar to:

  • CWL CommandLineTool
  • TES task containers
  • AWS Batch single-purpose images

That’s intentional.

You’re building the correct abstraction boundary.

About

Minimal cloud-agnostic container execution runtime for the OmniBioAI Tool Execution Service — enforces a strict input/output contract for tools running on AWS Batch, Azure Batch, and Kubernetes. Handles environment injection, output collection, and exit-code-based status reporting with no cloud-specific dependencies in tool images.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages