kestrel-cloud-runpod
Runpod GPU cloud provider for Kestrel Sovereign agents. Provision Pods, run LoRA training, manage Pod lifecycle, and submit queue-based Serverless jobs without using Runpod's v1 or GraphQL infrastructure APIs.
Installation
uv pip install kestrel-cloud-runpod
The feature is auto-discovered by Kestrel Sovereign via the kestrel_sovereign.features entry point — install it alongside kestrel-sovereign and RunPodFeature registers itself at startup.
Configuration
| Variable | Description |
|---|---|
RUNPOD_API_KEY |
RunPod API key (required) |
RUNPOD_CONTROL_PLANE_BASE_URL |
Optional beta/dev override; must end in /v2 |
RUNPOD_USER_AGENT |
Optional non-empty application User-Agent override |
Optional [runpod] section in kestrel.toml for default profile preferences.
What's provided
RunPodFeature— agent-facing tools for pod search, provisioning, training, lifecycle- Standalone API:
RunPodManagerfor direct programmatic use RunpodControlPlaneClient— typed v2 catalog, Pod, Serverless endpoint, worker/log, and billing clientRunpodServerlessClient— typed queue job run/status/cancel/retry/health client- RunPod-backed Ollama integration (when running large models on rented GPUs)
Architecture
- Runpod v2 execution platform — the accepted control-plane, Serverless, catalog inference, and private Ollama design.
Runpod has two distinct v2 services:
| Service | Default base | Authentication | Use |
|---|---|---|---|
| Control plane | https://v2-rest.runpod.io/v2 |
Bearer API key | Catalog, Pods, endpoint definitions, workers/logs, billing |
| Serverless data plane | https://api.runpod.ai/v2 |
Bearer API key | Queue job run, status, cancel, retry, and health |
Both clients set an explicit application User-Agent because the beta control plane rejects generic/default clients at its edge. Base URLs are injectable for testing but must end in /v2; there is no v1 or GraphQL production fallback.
Direct client example
from kestrel_cloud_runpod import RunpodControlPlaneClient, RunpodServerlessClient
from kestrel_cloud_runpod.models import ComputeProduct
control = RunpodControlPlaneClient(api_key="...")
offers = control.list_gpus(products=(ComputeProduct.SERVERLESS,))
jobs = RunpodServerlessClient(api_key="...")
job = jobs.run("endpoint-id", {"prompt": "hello"})
status = jobs.status("endpoint-id", job.id)
Create calls are never retried automatically. If a connection failure or 5xx makes a Pod, endpoint, or queue-job creation result ambiguous, the client raises RunPodAmbiguousResultError with reconcile_required = True. The compatibility manager preserves that type, and its LoRA/Ollama helpers halt instead of trying a replacement profile. A production caller must persist its attempt/fingerprint and reconcile by listing or status lookup before authorizing another create.
This package supplies the v2 vendor boundary; it does not turn the legacy in-memory manager TTL into a durable lease. Durable Serverless dispatch belongs to frinz#688, and durable private-inference ownership/reaping belongs to kestrel-cloud-runpod#9. Until those consumers land, process-local expiry is not a billing-safety guarantee.
Configuration migration from 0.2
Profiles no longer select a hardcoded gpu_type_id or record a cost_per_hr. Replace legacy fields with workload constraints:
[profiles.image]
name = "Large-memory image generation"
task_type = "image"
image_name = "runpod/kestrel-flux:latest"
min_vram_gb = 40
min_cuda_version = "12.8"
max_cost_per_hr = 3.00
gpu_count = 1
At Pod creation time, the direct provider queries v2 with product-specific availability, rejects offers outside the profile constraints, and records the selected GPU and offered live rate on the session. Legacy gpu_type_id, vram_gb, cost_per_hr, and template_id fields fail with migration guidance. Use registry_id for a v2 registry credential.
The old private CLI SSH helper is also gone. RunPodManager.get_logs() uses the v2 SSE Pod log endpoint. Arbitrary commands must be exposed as scoped workload HTTP operations.
OpenAPI beta pin
The reviewed v2 schema is pinned in vendor/runpod-v2-openapi.yaml with its checksum in vendor/runpod-v2-openapi.lock.json. Unit/contract CI validates the operations and shapes Kestrel consumes. A weekly/manual workflow compares the live schema and reports semantic drift without overwriting the pin.
Dependencies
kestrel-sovereign-sdk>=0.2,<1— baseFeature,tool,ToolCategory,BackendTypekestrel-sovereign>=0.7,<1—kestrel.tomlunified-config loader (runtime)httpx>=0.27,<1requests>=2.32,<3
Development
uv pip install -e '.[test]'
uv run pytest
python scripts/check_runpod_openapi.py --check-pin
An authenticated smoke test is opt-in, read-only, and lists the GPU catalog only:
RUNPOD_API_KEY=... uv run pytest --run-cloud tests/test_runpod_smoke.py
License
Apache-2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kestrel_cloud_runpod-0.3.0.tar.gz.
File metadata
- Download URL: kestrel_cloud_runpod-0.3.0.tar.gz
- Upload date:
- Size: 43.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
847be152865ed17a1dcf265d8b72c16df6563502ff60a0d3a7421b0b646ce8fa
|
|
| MD5 |
946bb97d296d55a165b102e8c3be39af
|
|
| BLAKE2b-256 |
9b0f79b0d73787ec1ef24762ab8c3fcbdba7d9def00ab3b2791057a4ca819124
|
Provenance
The following attestation bundles were made for kestrel_cloud_runpod-0.3.0.tar.gz:
Publisher:
publish.yml on KestrelSovereignAI/kestrel-cloud-runpod
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kestrel_cloud_runpod-0.3.0.tar.gz -
Subject digest:
847be152865ed17a1dcf265d8b72c16df6563502ff60a0d3a7421b0b646ce8fa - Sigstore transparency entry: 2313736194
- Sigstore integration time:
-
Permalink:
KestrelSovereignAI/kestrel-cloud-runpod@b5200059add45738e09a5ac60350d55dacfe5c0c -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/KestrelSovereignAI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b5200059add45738e09a5ac60350d55dacfe5c0c -
Trigger Event:
push
-
Statement type:
File details
Details for the file kestrel_cloud_runpod-0.3.0-py3-none-any.whl.
File metadata
- Download URL: kestrel_cloud_runpod-0.3.0-py3-none-any.whl
- Upload date:
- Size: 49.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74e7da7d33df83419cec2414f342c532f71a8d2289dcfede79d09cae043d64f7
|
|
| MD5 |
017967538fcb784f7a06f51634b393a0
|
|
| BLAKE2b-256 |
a40b5f5cf8944385782c49c076d22bb6fef0fb928b29874b4fe5830476e90ffa
|
Provenance
The following attestation bundles were made for kestrel_cloud_runpod-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on KestrelSovereignAI/kestrel-cloud-runpod
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kestrel_cloud_runpod-0.3.0-py3-none-any.whl -
Subject digest:
74e7da7d33df83419cec2414f342c532f71a8d2289dcfede79d09cae043d64f7 - Sigstore transparency entry: 2313736279
- Sigstore integration time:
-
Permalink:
KestrelSovereignAI/kestrel-cloud-runpod@b5200059add45738e09a5ac60350d55dacfe5c0c -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/KestrelSovereignAI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b5200059add45738e09a5ac60350d55dacfe5c0c -
Trigger Event:
push
-
Statement type: