Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/agentex/lib/cli/handlers/deploy_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,9 @@ def merge_deployment_configs(
"memory": manifest.deployment.global_config.resources.limits.memory,
},
},
# Enable autoscaling by default for production deployments
# Opt-in only: a crash loop's restart CPU burn reads as load and scales it to max.
"autoscaling": {
"enabled": True,
"enabled": False,
"minReplicas": 1,
"maxReplicas": 10,
"targetCPUUtilizationPercentage": 50,
Expand All @@ -307,9 +307,8 @@ def merge_deployment_configs(
if temporal_config:
helm_values[TEMPORAL_WORKER_KEY] = {
"enabled": True,
# Enable autoscaling for temporal workers as well
"autoscaling": {
"enabled": True,
"enabled": False,
"minReplicas": 1,
"maxReplicas": 10,
"targetCPUUtilizationPercentage": 50,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal:
enabled: false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal:
enabled: false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal:
enabled: false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true

Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal:
enabled: false

Expand Down
3 changes: 3 additions & 0 deletions src/agentex/lib/cli/templates/default/environments.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal:
enabled: false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true

3 changes: 3 additions & 0 deletions src/agentex/lib/cli/templates/sync-codex/environments.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true

Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true

Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true

Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true

Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true

3 changes: 3 additions & 0 deletions src/agentex/lib/cli/templates/sync/environments.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true

Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal-worker:
enabled: true
replicaCount: 2
Expand All @@ -61,4 +64,7 @@ environments:
memory: "1Gi"
limits:
cpu: "1000m"
memory: "2Gi"
memory: "2Gi"
# Autoscaling here is separate from the block above, so opt in twice.
# autoscaling:
# enabled: true
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal-worker:
enabled: true
replicaCount: 2
Expand All @@ -61,4 +64,7 @@ environments:
memory: "1Gi"
limits:
cpu: "1000m"
memory: "2Gi"
memory: "2Gi"
# Autoscaling here is separate from the block above, so opt in twice.
# autoscaling:
# enabled: true
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal-worker:
enabled: true
replicaCount: 2
Expand All @@ -61,4 +64,7 @@ environments:
memory: "1Gi"
limits:
cpu: "1000m"
memory: "2Gi"
memory: "2Gi"
# Autoscaling here is separate from the block above, so opt in twice.
# autoscaling:
# enabled: true
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal-worker:
enabled: true
replicaCount: 2
Expand All @@ -61,4 +64,7 @@ environments:
memory: "1Gi"
limits:
cpu: "1000m"
memory: "2Gi"
memory: "2Gi"
# Autoscaling here is separate from the block above, so opt in twice.
# autoscaling:
# enabled: true
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal-worker:
enabled: true
replicaCount: 2
Expand All @@ -61,4 +64,7 @@ environments:
memory: "1Gi"
limits:
cpu: "1000m"
memory: "2Gi"
memory: "2Gi"
# Autoscaling here is separate from the block above, so opt in twice.
# autoscaling:
# enabled: true
8 changes: 7 additions & 1 deletion src/agentex/lib/cli/templates/temporal/environments.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ environments:
limits:
cpu: "1000m"
memory: "2Gi"
# Autoscaling is opt-in. Unset keys inherit maxReplicas 10 and a 50% CPU target.
# autoscaling:
# enabled: true
temporal-worker:
enabled: true
replicaCount: 2
Expand All @@ -61,4 +64,7 @@ environments:
memory: "1Gi"
limits:
cpu: "1000m"
memory: "2Gi"
memory: "2Gi"
# Autoscaling here is separate from the block above, so opt in twice.
# autoscaling:
# enabled: true
98 changes: 98 additions & 0 deletions tests/lib/cli/test_deploy_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""Tests for helm value merging in deploy_handlers."""

from __future__ import annotations

from typing import Any

import pytest

from agentex.config.agent_config import AgentConfig
from agentex.config.build_config import BuildConfig, BuildContext
from agentex.config.agent_configs import TemporalConfig, TemporalWorkflowConfig
from agentex.config.agent_manifest import AgentManifest
from agentex.config.deployment_config import ImageConfig, DeploymentConfig
from agentex.config.environment_config import AgentAuthConfig, AgentEnvironmentConfig
from agentex.lib.cli.handlers.deploy_handlers import (
TEMPORAL_WORKER_KEY,
InputDeployOverrides,
merge_deployment_configs,
)


def _manifest(*, temporal: bool) -> AgentManifest:
return AgentManifest(
build=BuildConfig(context=BuildContext(root=".", dockerfile="Dockerfile", dockerignore=None)),
agent=AgentConfig(
name="test-agent",
acp_type="async",
description="An AgentEx agent",
temporal=TemporalConfig(
enabled=True,
workflows=[TemporalWorkflowConfig(name="test-agent", queue_name="test_agent_queue")],
)
if temporal
else None,
),
deployment=DeploymentConfig(image=ImageConfig(repository="registry.example.com/test-agent", tag="v1")),
)


def _env_config(helm_overrides: dict[str, Any] | None = None) -> AgentEnvironmentConfig:
return AgentEnvironmentConfig(
auth=AgentAuthConfig(principal={"user_id": "test-user", "account_id": "test-account"}),
helm_overrides=helm_overrides or {},
)


def _merge(*, temporal: bool = False, env_config: AgentEnvironmentConfig | None = None) -> dict[str, Any]:
return merge_deployment_configs(
manifest=_manifest(temporal=temporal),
agent_env_config=env_config,
deploy_overrides=InputDeployOverrides(),
manifest_path="manifest.yaml",
)


class TestAutoscalingDefaults:
"""Autoscaling is opt-in, and the bounds stay available for whoever opts in."""

def test_disabled_by_default(self):
assert _merge()["autoscaling"]["enabled"] is False

def test_disabled_by_default_for_temporal_worker(self):
helm_values = _merge(temporal=True)
assert helm_values[TEMPORAL_WORKER_KEY]["autoscaling"]["enabled"] is False

@pytest.mark.parametrize(
"key,expected", [("minReplicas", 1), ("maxReplicas", 10), ("targetCPUUtilizationPercentage", 50)]
)
def test_bounds_survive_an_opt_in(self, key: str, expected: int):
"""An opt-in that sets only `enabled` must still inherit the CPU target and replica bounds."""
helm_values = _merge(env_config=_env_config({"autoscaling": {"enabled": True}}))

assert helm_values["autoscaling"]["enabled"] is True
assert helm_values["autoscaling"][key] == expected

def test_temporal_worker_opts_in_separately(self):
"""The worker HPA is its own block, so opting the agent in leaves the worker off."""
helm_values = _merge(
temporal=True,
env_config=_env_config({"autoscaling": {"enabled": True}}),
)

assert helm_values["autoscaling"]["enabled"] is True
assert helm_values[TEMPORAL_WORKER_KEY]["autoscaling"]["enabled"] is False

opted_in = _merge(
temporal=True,
env_config=_env_config({TEMPORAL_WORKER_KEY: {"autoscaling": {"enabled": True}}}),
)

assert opted_in[TEMPORAL_WORKER_KEY]["autoscaling"]["enabled"] is True
assert opted_in[TEMPORAL_WORKER_KEY]["autoscaling"]["targetCPUUtilizationPercentage"] == 50

def test_opt_in_overrides_win_over_the_base(self):
helm_values = _merge(env_config=_env_config({"autoscaling": {"enabled": True, "maxReplicas": 3}}))

assert helm_values["autoscaling"]["maxReplicas"] == 3
assert helm_values["autoscaling"]["targetCPUUtilizationPercentage"] == 50
Loading