Portable, cloud-agnostic execution runtime for OmniBioAI tools
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
- (future) Kubernetes Jobs
- (future) TES-compatible HPC schedulers
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.
-
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)
- A workflow engine
- A scheduler
- An LLM executor
- A UI layer
Those responsibilities live elsewhere in OmniBioAI.
All tools executed via omnibioai-tool-runtime must follow this contract.
| 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.
omnibioai-tool-runtime/
├── Dockerfile
├── README.md
├── pyproject.toml
├── omni_tool_runtime/
│ ├── __init__.py
│ ├── result_uri.py # URI parsing & dispatch
│ ├── upload_result.py # Unified upload logic
│ └── uploaders/
│ ├── s3_uploader.py
│ └── azureblob_uploader.py
├── tools/
│ └── echo_test/
│ ├── __init__.py
│ └── run.py
└── tests/
This is the reference implementation for all future tools.
- Reads
INPUTS_JSON - Echoes a value
- Writes
results.json - Uploads results to configured storage backend
# 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()upload_result() automatically detects the backend:
| Backend | URI Example |
|---|---|
| AWS | s3://bucket/prefix/run_id/results.json |
| Azure | azureblob://account/container/path/results.json |
The runtime:
- Serializes result as JSON
- Uploads to correct backend
- Prints result to stdout (for debugging)
Adapters never upload results themselves.
From repository root:
docker build -t man4ish/omnibioai-tool-runtime:latest .Verify:
docker images | grep omnibioai-tool-runtimedocker run --rm \
-e TOOL_ID=echo_test \
-e RUN_ID=local-test-1 \
-e INPUTS_JSON='{"text":"hello world"}' \
-e RESOURCES_JSON='{}' \
man4ish/omnibioai-tool-runtime:latestExpected:
- JSON output printed to stdout
- No upload attempted if no result URI is provided
- Image:
man4ish/omnibioai-tool-runtime:latest - Command override:
["python", "-m", "tools.echo_test.run"]S3_RESULT_URIprovided byAwsBatchAdapter- IAM Role handles S3 auth
- Image:
man4ish/omnibioai-tool-runtime:latest - Command:
python -m tools.echo_test.runRESULT_URI=azureblob://...- Managed Identity handles Blob auth
docker push man4ish/omnibioai-tool-runtime:latestaz acr login --name YOUR_ACR
docker tag man4ish/omnibioai-tool-runtime:latest YOUR_ACR.azurecr.io/omnibioai-tool-runtime:latest
docker push YOUR_ACR.azurecr.io/omnibioai-tool-runtime:latestmkdir tools/my_new_tool
touch tools/my_new_tool/__init__.py
touch tools/my_new_tool/run.pyRules:
- Must read env vars
- Must write result via
upload_result() - Must be deterministic
AWS Batch
job_definition_map:
my_new_tool: "omnibioai-my-new-tool:1"Azure Batch
tools:
my_new_tool:
image: "man4ish/omnibioai-tool-runtime:latest"
command: ["python", "-m", "tools.my_new_tool.run"]- Unified runtime image
- AWS Batch support
- Azure Batch support
- S3 + Azure Blob uploads
- Deterministic execution contract
- Reference
echo_testtool
- No workflow orchestration
- No retry logic
- No state machine
- No scheduling policy
- Tool generator CLI (
omnibioai tool new) - Structured logging
- Result size validation
- Runtime version pinning
- Kubernetes Job adapter support
- Streaming stdout to object storage
- Tool-level resource enforcement
- Tool metadata introspection
- Signed result manifests
- Provenance hashing
- Deterministic replay support
- Cross-cloud artifact mirroring
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.
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.