fix(cli): keep AWS deployments on dev until serverless is supported

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
Hari Dhanushkodi
2026-10-16 18:50:31 +00:00
co-authored by open-swe[bot] <open-swe@users.noreply.github.com>
parent a833171538
commit dcdcb13a99
4 changed files with 116 additions and 3 deletions
+11 -3
View File
@@ -1548,6 +1548,11 @@ def _resolve_or_create(
)
if found is not None:
return found.id, step
if ctx.endpoints.is_aws and ctx.deployment_type == "dev_zero":
raise click.UsageError(
"Serverless deployments are not supported on AWS yet. "
"Use --deployment-type dev instead."
)
try:
created, step = _create_deployment(
ctx.client,
@@ -2214,8 +2219,8 @@ def _deploy_base_options(
click.option(
"--deployment-type",
type=click.Choice(["serverless", "dedicated", "dev", "prod"]),
default="serverless",
show_default=True,
default=None,
show_default="serverless; dev on AWS",
help=(
"Deployment type (used when creating a new deployment): "
"serverless (scale to zero) or dedicated (prod); "
@@ -2396,7 +2401,7 @@ def _deploy_cmd(
host_url: str | None,
api_key: str | None,
deployment_id: str | None,
deployment_type: str,
deployment_type: str | None,
name: str | None,
agent_id: str | None,
environment: str | None,
@@ -2488,6 +2493,9 @@ def _deploy_cmd(
)
client = _create_host_backend_client(host_url, api_key, env_vars=env_vars)
deployment_type = deployment_type or (
"dev" if client.endpoints.is_aws else "serverless"
)
try:
tracked_packages = find_tracked_packages(config, config_json) or None
except Exception as exc:
+4
View File
@@ -44,6 +44,10 @@ class ControlPlaneEndpoints:
f".{CLOUD_CONTROL_PLANE_HOST}"
)
@property
def is_aws(self) -> bool:
return urlparse(self.control_plane_url).hostname == "aws.api.host.langchain.com"
@classmethod
def from_control_plane_url(cls, url: str) -> ControlPlaneEndpoints:
control_plane_url = url.rstrip("/")
@@ -344,6 +344,81 @@ def deploy_project(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> DeployPro
return DeployProject(control_plane, docker, timeline, uploads)
@pytest.mark.parametrize("build_mode", ["--no-remote", "--remote"])
@pytest.mark.parametrize("deployment_args", [(), ("--deployment-type", "dev")])
def test_aws_deploy_uses_dev(
deploy_project: DeployProject, build_mode: str, deployment_args: tuple[str, ...]
) -> None:
result = deploy_project.run(
build_mode, *deployment_args, host_url="https://aws.api.host.langchain.com"
)
assert result.exit_code == 0, result.output
assert deploy_project.control_plane.bodies[CREATE_DEPLOYMENT]["source_config"] == {
"deployment_type": "dev"
}
@pytest.mark.parametrize("build_mode", ["--no-remote", "--remote"])
def test_aws_deploy_rejects_serverless_before_creating_or_building(
deploy_project: DeployProject, build_mode: str
) -> None:
result = deploy_project.run(
build_mode,
"--deployment-type",
"serverless",
host_url="https://aws.api.host.langchain.com",
)
assert result.exit_code == 2, result.output
assert "Serverless deployments are not supported on AWS yet" in result.output
assert "Use --deployment-type dev instead" in result.output
assert deploy_project.timeline == [LIST_DEPLOYMENTS]
@pytest.mark.parametrize("endpoint_source", ["environment", "dotenv"])
def test_aws_default_is_resolved_from_langsmith_endpoint(
deploy_project: DeployProject,
monkeypatch: pytest.MonkeyPatch,
endpoint_source: str,
) -> None:
endpoint = "https://aws.api.smith.langchain.com"
if endpoint_source == "environment":
monkeypatch.setenv("LANGSMITH_ENDPOINT", endpoint)
else:
Path(".env").write_text(f"LANGSMITH_ENDPOINT={endpoint}\n")
result = CliRunner().invoke(
cli,
[
"deploy",
"--api-key",
"test-key",
"--name",
"my-app",
"--no-input",
"--no-wait",
"--remote",
],
)
assert result.exit_code == 0, result.output
assert deploy_project.control_plane.bodies[CREATE_DEPLOYMENT]["source_config"] == {
"deployment_type": "dev"
}
def test_explicit_host_takes_precedence_over_aws_langsmith_endpoint(
deploy_project: DeployProject, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("LANGSMITH_ENDPOINT", "https://aws.api.smith.langchain.com")
result = deploy_project.run("--remote", host_url=CLOUD_CONTROL_PLANE_URL)
assert result.exit_code == 0, result.output
assert deploy_project.control_plane.bodies[CREATE_DEPLOYMENT]["source_config"] == {
"deployment_type": "dev_zero"
}
def test_first_local_deploy_creates_then_builds_pushes_and_updates_in_order(
deploy_project: DeployProject,
) -> None:
@@ -10,6 +10,32 @@ from langgraph_cli.host_backend import (
)
@pytest.mark.parametrize(
("host_url", "langsmith_endpoint", "expected"),
[
("https://aws.api.host.langchain.com/", None, True),
("https://AWS.api.host.langchain.com:443", None, True),
(None, "https://aws.api.smith.langchain.com", True),
(None, None, False),
("https://eu.api.host.langchain.com", None, False),
("https://apac.api.host.langchain.com", None, False),
("https://aws.example.com/api-host", None, False),
("https://aws.api.host.langchain.com.example.com", None, False),
(
"https://api.host.langchain.com",
"https://aws.api.smith.langchain.com",
False,
),
],
)
def test_aws_detection_uses_the_resolved_control_plane_host(
host_url: str | None, langsmith_endpoint: str | None, expected: bool
) -> None:
endpoints = ControlPlaneEndpoints.resolve(host_url, langsmith_endpoint)
assert endpoints.is_aws is expected
def test_constructor_strips_trailing_slash():
c = HostBackendClient("https://api.example.com/", "key")
assert c.base_url == "https://api.example.com"