V1 Changes to Support Path Based Routing (#13120)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
chuckbutkus
2026-03-02 22:37:37 -05:00
committed by GitHub
parent 4dab34e7b0
commit 0c7ce4ad48
5 changed files with 241 additions and 40 deletions

View File

@@ -4,6 +4,7 @@ import logging
import os
from dataclasses import dataclass
from typing import Any, AsyncGenerator, Union
from urllib.parse import urlparse
from uuid import UUID
import base62
@@ -142,12 +143,13 @@ class RemoteSandboxService(SandboxService):
exposed_urls = []
url = runtime.get('url', None)
if url:
runtime_id = runtime['runtime_id']
exposed_urls.append(
ExposedUrl(name=AGENT_SERVER, url=url, port=AGENT_SERVER_PORT)
)
vscode_url = (
_build_service_url(url, 'vscode')
+ f'/?tkn={session_api_key}&folder=%2Fworkspace%2Fproject'
_build_service_url(url, 'vscode', runtime_id)
+ f'?tkn={session_api_key}&folder=%2Fworkspace%2Fproject'
)
exposed_urls.append(
ExposedUrl(name=VSCODE, url=vscode_url, port=VSCODE_PORT)
@@ -155,14 +157,14 @@ class RemoteSandboxService(SandboxService):
exposed_urls.append(
ExposedUrl(
name=WORKER_1,
url=_build_service_url(url, 'work-1'),
url=_build_service_url(url, 'work-1', runtime_id),
port=WORKER_1_PORT,
)
)
exposed_urls.append(
ExposedUrl(
name=WORKER_2,
url=_build_service_url(url, 'work-2'),
url=_build_service_url(url, 'work-2', runtime_id),
port=WORKER_2_PORT,
)
)
@@ -663,9 +665,21 @@ class RemoteSandboxService(SandboxService):
return results
def _build_service_url(url: str, service_name: str):
scheme, host_and_path = url.split('://')
return scheme + '://' + service_name + '-' + host_and_path
def _build_service_url(url: str, service_name: str, runtime_id: str) -> str:
"""Build a service URL for the given service name.
Handles both path-based and subdomain-based routing:
- Path mode (url path starts with /{runtime_id}): returns {scheme}://{netloc}/{runtime_id}/{service_name}
- Subdomain mode: returns {scheme}://{service_name}-{netloc}{path}
"""
parsed = urlparse(url)
scheme, netloc, path = parsed.scheme, parsed.netloc, parsed.path or '/'
# Path mode if runtime_url path starts with /{id}
path_mode = path.startswith(f'/{runtime_id}')
if path_mode:
return f'{scheme}://{netloc}/{runtime_id}/{service_name}'
else:
return f'{scheme}://{service_name}-{netloc}{path}'
async def poll_agent_servers(api_url: str, api_key: str, sleep_interval: int):

View File

@@ -13,7 +13,7 @@ from openhands.sdk.utils.models import DiscriminatedUnionMixin
# The version of the agent server to use for deployments.
# Typically this will be the same as the values from the pyproject.toml
AGENT_SERVER_IMAGE = 'ghcr.io/openhands/agent-server:010e847-python'
AGENT_SERVER_IMAGE = 'ghcr.io/openhands/agent-server:2c1e72a-python'
class SandboxSpecService(ABC):