mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-27 01:11:40 +00:00
feat(koyeb): add Koyeb backend support for cloud execution and environment management
This commit is contained in:
parent
57e33cf284
commit
abd5eacb6e
11 changed files with 479 additions and 64 deletions
|
|
@ -437,7 +437,8 @@ DEFAULT_CONFIG = {
|
|||
"singularity_image": "docker://nikolaik/python-nodejs:python3.11-nodejs20",
|
||||
"modal_image": "nikolaik/python-nodejs:python3.11-nodejs20",
|
||||
"daytona_image": "nikolaik/python-nodejs:python3.11-nodejs20",
|
||||
# Container resource limits (docker, singularity, modal, daytona — ignored for local/ssh)
|
||||
"koyeb_image": "koyeb/sandbox:latest",
|
||||
# Container resource limits (docker, singularity, modal, daytona, koyeb — ignored for local/ssh)
|
||||
"container_cpu": 1,
|
||||
"container_memory": 5120, # MB (default 5GB)
|
||||
"container_disk": 51200, # MB (default 50GB)
|
||||
|
|
@ -3694,6 +3695,10 @@ def show_config():
|
|||
print(f" Daytona image: {terminal.get('daytona_image', 'nikolaik/python-nodejs:python3.11-nodejs20')}")
|
||||
daytona_key = get_env_value('DAYTONA_API_KEY')
|
||||
print(f" API key: {'configured' if daytona_key else '(not set)'}")
|
||||
elif terminal.get('backend') == 'koyeb':
|
||||
print(f" Koyeb image: {terminal.get('koyeb_image', 'koyeb/sandbox:latest')}")
|
||||
koyeb_token = get_env_value('KOYEB_API_TOKEN')
|
||||
print(f" API token: {'configured' if koyeb_token else '(not set)'}")
|
||||
elif terminal.get('backend') == 'ssh':
|
||||
ssh_host = get_env_value('TERMINAL_SSH_HOST')
|
||||
ssh_user = get_env_value('TERMINAL_SSH_USER')
|
||||
|
|
@ -3886,6 +3891,7 @@ def set_config_value(key: str, value: str):
|
|||
"terminal.singularity_image": "TERMINAL_SINGULARITY_IMAGE",
|
||||
"terminal.modal_image": "TERMINAL_MODAL_IMAGE",
|
||||
"terminal.daytona_image": "TERMINAL_DAYTONA_IMAGE",
|
||||
"terminal.koyeb_image": "TERMINAL_KOYEB_IMAGE",
|
||||
"terminal.docker_mount_cwd_to_workspace": "TERMINAL_DOCKER_MOUNT_CWD_TO_WORKSPACE",
|
||||
"terminal.cwd": "TERMINAL_CWD",
|
||||
"terminal.timeout": "TERMINAL_TIMEOUT",
|
||||
|
|
|
|||
|
|
@ -777,6 +777,21 @@ def run_doctor(args):
|
|||
check_fail("daytona SDK not installed", "(pip install daytona)")
|
||||
issues.append("Install daytona SDK: pip install daytona")
|
||||
|
||||
# Koyeb (if using koyeb backend)
|
||||
if terminal_env == "koyeb":
|
||||
koyeb_token = os.getenv("KOYEB_API_TOKEN")
|
||||
if koyeb_token:
|
||||
check_ok("Koyeb API token", "(configured)")
|
||||
else:
|
||||
check_fail("KOYEB_API_TOKEN not set", "(required for TERMINAL_ENV=koyeb)")
|
||||
issues.append("Set KOYEB_API_TOKEN environment variable")
|
||||
try:
|
||||
from koyeb import Sandbox # noqa: F401 — SDK presence check
|
||||
check_ok("koyeb SDK", "(installed)")
|
||||
except ImportError:
|
||||
check_fail("koyeb SDK not installed", "(pip install koyeb-sdk)")
|
||||
issues.append("Install koyeb SDK: pip install koyeb-sdk")
|
||||
|
||||
# Node.js + agent-browser (for browser automation tools)
|
||||
if shutil.which("node"):
|
||||
check_ok("Node.js")
|
||||
|
|
|
|||
|
|
@ -1182,11 +1182,12 @@ def setup_terminal_backend(config: dict):
|
|||
"Modal - serverless cloud sandbox",
|
||||
"SSH - run on a remote machine",
|
||||
"Daytona - persistent cloud development environment",
|
||||
"Koyeb - cloud sandbox execution",
|
||||
]
|
||||
idx_to_backend = {0: "local", 1: "docker", 2: "modal", 3: "ssh", 4: "daytona"}
|
||||
backend_to_idx = {"local": 0, "docker": 1, "modal": 2, "ssh": 3, "daytona": 4}
|
||||
idx_to_backend = {0: "local", 1: "docker", 2: "modal", 3: "ssh", 4: "daytona", 5: "koyeb"}
|
||||
backend_to_idx = {"local": 0, "docker": 1, "modal": 2, "ssh": 3, "daytona": 4, "koyeb": 5}
|
||||
|
||||
next_idx = 5
|
||||
next_idx = 6
|
||||
if is_linux:
|
||||
terminal_choices.append("Singularity/Apptainer - HPC-friendly container")
|
||||
idx_to_backend[next_idx] = "singularity"
|
||||
|
|
@ -1441,6 +1442,64 @@ def setup_terminal_backend(config: dict):
|
|||
|
||||
_prompt_container_resources(config)
|
||||
|
||||
elif selected_backend == "koyeb":
|
||||
print_success("Terminal backend: Koyeb")
|
||||
print_info("Cloud sandbox execution via Koyeb.")
|
||||
print_info("Sign up at: https://www.koyeb.com")
|
||||
|
||||
# Check if koyeb SDK is installed
|
||||
try:
|
||||
__import__("koyeb")
|
||||
except ImportError:
|
||||
print_info("Installing koyeb SDK...")
|
||||
import subprocess
|
||||
|
||||
uv_bin = shutil.which("uv")
|
||||
if uv_bin:
|
||||
result = subprocess.run(
|
||||
[uv_bin, "pip", "install", "--python", sys.executable, "koyeb-sdk"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
else:
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-m", "pip", "install", "koyeb-sdk"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if result.returncode == 0:
|
||||
print_success("koyeb SDK installed")
|
||||
else:
|
||||
print_warning("Install failed — run manually: pip install koyeb-sdk")
|
||||
if result.stderr:
|
||||
print_info(f" Error: {result.stderr.strip().splitlines()[-1]}")
|
||||
|
||||
# Koyeb API token
|
||||
print()
|
||||
existing_key = get_env_value("KOYEB_API_TOKEN")
|
||||
if existing_key:
|
||||
print_info(" Koyeb API token: already configured")
|
||||
if prompt_yes_no(" Update API token?", False):
|
||||
api_key = prompt(" Koyeb API token", password=True)
|
||||
if api_key:
|
||||
save_env_value("KOYEB_API_TOKEN", api_key)
|
||||
print_success(" Updated")
|
||||
else:
|
||||
api_key = prompt(" Koyeb API token", password=True)
|
||||
if api_key:
|
||||
save_env_value("KOYEB_API_TOKEN", api_key)
|
||||
print_success(" Configured")
|
||||
|
||||
# Koyeb image
|
||||
current_image = config.get("terminal", {}).get(
|
||||
"koyeb_image", "koyeb/sandbox:latest"
|
||||
)
|
||||
image = prompt(" Sandbox image", current_image)
|
||||
config["terminal"]["koyeb_image"] = image
|
||||
save_env_value("TERMINAL_KOYEB_IMAGE", image)
|
||||
|
||||
_prompt_container_resources(config)
|
||||
|
||||
elif selected_backend == "ssh":
|
||||
print_success("Terminal backend: SSH")
|
||||
print_info("Run commands on a remote machine via SSH.")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue