Run tasks
Task submission supports local two-file directories or SDK file-content mappings. The SDK reads files and sends their contents; the remote machine does not need access to the client directory. Named Runner / Dataset submissions use the APIServer catalog; the platform downloads the problem when executing it.
Submit and inspect
First prepare ./my-task and the connection configuration from Quickstart:
el task submit ./my-task --wait
el task status TRIAL_ID
el task snapshot TRIAL_ID
el task result TRIAL_ID
el task stop TRIAL_ID
Replace TRIAL_ID with the ID returned on submission. HTTP submission returns immediately by default; --wait explicitly waits. Local CLI submission waits for execution to end. result itself does not wait. The CLI has no task logs, task cancel, or task wait subcommands.
Harbor Runner
After registering the Runner and Dataset in your APIServer catalog and configuring the connection, run the fix-git task:
el task submit \
--runner envhub/harbor@0.23.0 \
--dataset envloop/terminal-bench-2-1-lite@1.0.1 \
--task-id terminal-bench/fix-git \
--queue-id default \
--priority 10 \
--wait
The example pins Dataset version 1.0.1; the selected names and versions must exist in your catalog. It does not establish production catalog availability or a verified benchmark result.
No --command is needed: runner.toml declares main.sh, so the platform runs bash main.sh. A Python Runner declaring main.py similarly uses python main.py. Use --command only to customize startup. The Harbor Runner requires an execution node with Docker-in-Docker (DinD) support enabled.
Inline files with Python
from envloop import Client
files = {
"runner.toml": '''schema_version = "envhub.runner/v1"
[runner]
name = "examples/inline"
version = "1"
[execution]
entrypoint = "main.py"
timeout_sec = 10
''',
"main.py": 'print("inline hello")\n',
}
with Client.remote() as client:
trial = client.tasks.submit(files, request_id="inline-hello-001")
final = client.tasks.wait(trial["trial_id"], timeout=60)
print(final["status"])
print(client.tasks.result(trial["trial_id"])["stdout"])
The first run should return succeeded, with stdout containing inline hello and a newline. Reusing the same request_id reuses the original Trial; use a new value to rerun intentionally.
Results and artifacts
The result dictionary includes stdout, stderr, and outputs. Each output contains name, content, size, and sha256. Only artifacts declared by the task are returned as outputs; see Task format. SHA-256 covers raw bytes; content is decoded text and should not be re-encoded to verify arbitrary binary files.
Local logs remain in logs/trials/<trial_id>/ under the current directory at startup, including stdout.log, stderr.log, and manifest.json, independently of work_dir. Remote execution logs are not written to this client directory.
Timeout and cancellation
tasks.wait(timeout=...) limits client waiting time; a TimeoutError does not cancel execution. execution.timeout_sec limits task execution time. Explicitly call tasks.stop() to stop; the backend may reject cancellation. For example, E2B currently returns CANCELLATION_UNSUPPORTED, which does not mean cloud resources have been reclaimed.
See Troubleshooting for error handling.