Skip to content
Merged
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
22 changes: 20 additions & 2 deletions frontend/src/automations/templateProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@ const AGENTKIT_BASE_IMAGES: Record<CloudProvider, string> = {
"agentkit-prod-public-ap-southeast-1.cr.bytepluses.com/base/py-simple:python3.12-bookworm-slim-latest",
};

const VEADK_VERSION = "1.1.9";
const VOLCENGINE_PYPI_INDEXES = [
"https://repo.huaweicloud.com/repository/pypi/simple",
"https://mirrors.aliyun.com/pypi/simple/",
"https://pypi.org/simple",
] as const;

function buildPythonDependencyInstall(cloudProvider: CloudProvider): string {
if (cloudProvider !== "volcengine") {
return "RUN uv pip install -r requirements.txt";
}

const attempts = VOLCENGINE_PYPI_INDEXES.map(
(index) => `uv pip install --index-url ${index} -r requirements.txt`,
);
return `RUN ${attempts.join(" || \\\n ")}`;
}

function buildEnvExample(cloudProvider: CloudProvider): string {
const secrets = cloudCredentialSecretNames(cloudProvider);
const providerName = cloudProviderDisplayName(cloudProvider);
Expand Down Expand Up @@ -115,7 +133,7 @@ root_agent = Agent(
tools=[get_city_weather],
)
`,
"requirements.txt": `veadk-python==1.1.6
"requirements.txt": `veadk-python==${VEADK_VERSION}
agentkit-sdk-python==0.8.4
google-adk==2.1.0
lark-channel-sdk==1.2.0
Expand All @@ -128,7 +146,7 @@ ENV UV_SYSTEM_PYTHON=1 UV_COMPILE_BYTECODE=1 PYTHONUNBUFFERED=1
WORKDIR /app

COPY requirements.txt ./
RUN uv pip install -r requirements.txt
${buildPythonDependencyInstall(cloudProvider)}

COPY . .

Expand Down
18 changes: 17 additions & 1 deletion frontend/src/ui/cloudEnvironmentDockerfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ const AGENTKIT_BASE_IMAGES: Record<CloudProvider, string> = {
byteplus:
"agentkit-prod-public-ap-southeast-1.cr.bytepluses.com/base/py-simple:python3.12-bookworm-slim-latest",
};
const VOLCENGINE_PYPI_INDEXES = [
"https://repo.huaweicloud.com/repository/pypi/simple",
"https://mirrors.aliyun.com/pypi/simple/",
"https://pypi.org/simple",
] as const;

const LARK_CLI_VERSION = "1.0.87";
const LARK_CLI_SHA256 = {
Expand Down Expand Up @@ -66,6 +71,17 @@ function githubReleaseUrls(
: [official, mirror];
}

function renderPythonDependencyInstall(cloudProvider: CloudProvider): string {
if (cloudProvider !== "volcengine") {
return "RUN uv pip install -r requirements.txt";
}

const attempts = VOLCENGINE_PYPI_INDEXES.map(
(index) => `uv pip install --index-url ${index} -r requirements.txt`,
);
return `RUN ${attempts.join(" || \\\n ")}`;
}

export function buildCloudEnvironmentDockerfile(
cloudProvider: CloudProvider,
cliTools: CloudCliToolId[],
Expand Down Expand Up @@ -123,7 +139,7 @@ export function buildCloudEnvironmentDockerfile(
"",
"# Install Python dependencies before copying the source for better layer caching.",
"COPY requirements.txt requirements.txt",
"RUN uv pip install -r requirements.txt",
renderPythonDependencyInstall(cloudProvider),
"",
"# Copy the Agent application and configure its runtime entrypoint.",
"EXPOSE 8000",
Expand Down
13 changes: 12 additions & 1 deletion frontend/tests/automation-artifacts.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ test("generates the basic Studio project and Runtime delivery workflow in fronte
assert.equal(
files["requirements.txt"],
[
"veadk-python==1.1.6",
"veadk-python==1.1.9",
"agentkit-sdk-python==0.8.4",
"google-adk==2.1.0",
"lark-channel-sdk==1.2.0",
Expand All @@ -49,6 +49,14 @@ test("generates the basic Studio project and Runtime delivery workflow in fronte
"",
].join("\n"),
);
const huawei = "https://repo.huaweicloud.com/repository/pypi/simple";
const aliyun = "https://mirrors.aliyun.com/pypi/simple/";
const pypi = "https://pypi.org/simple";
assert.match(files.Dockerfile, new RegExp(huawei.replaceAll(".", "\\.")));
assert.match(files.Dockerfile, new RegExp(aliyun.replaceAll(".", "\\.")));
assert.match(files.Dockerfile, new RegExp(pypi.replaceAll(".", "\\.")));
assert.ok(files.Dockerfile.indexOf(huawei) < files.Dockerfile.indexOf(aliyun));
assert.ok(files.Dockerfile.indexOf(aliyun) < files.Dockerfile.indexOf(pypi));
assert.match(files["README.md"], /python app\.py/);

const workflow = buildRuntimeDeliveryWorkflow({
Expand Down Expand Up @@ -86,6 +94,9 @@ test("generates BytePlus template and Runtime delivery workflow in frontend", as
assert.match(files[".env.example"], /AGENTKIT_CLOUD_PROVIDER=byteplus/);
assert.match(files[".env.example"], /https:\/\/ark\.ap-southeast\.bytepluses\.com\/api\/v3/);
assert.doesNotMatch(files[".env.example"], /VOLCENGINE_ACCESS_KEY=/);
assert.match(files.Dockerfile, /RUN uv pip install -r requirements\.txt/);
assert.doesNotMatch(files.Dockerfile, /repo\.huaweicloud\.com/);
assert.doesNotMatch(files.Dockerfile, /mirrors\.aliyun\.com/);

const workflow = buildRuntimeDeliveryWorkflow({
baseBranch: "main",
Expand Down
10 changes: 10 additions & 0 deletions frontend/tests/cloudEnvironment.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@ test("builds an editable provider-specific Dockerfile preview", () => {
assert.match(volcengine, /# Install Lark CLI/);
assert.match(volcengine, /# Install Python dependencies/);
assert.match(volcengine, /# Copy the Agent application/);
const huawei = "https://repo.huaweicloud.com/repository/pypi/simple";
const aliyun = "https://mirrors.aliyun.com/pypi/simple/";
const pypi = "https://pypi.org/simple";
assert.match(volcengine, new RegExp(huawei.replaceAll(".", "\\.")));
assert.match(volcengine, new RegExp(aliyun.replaceAll(".", "\\.")));
assert.match(volcengine, new RegExp(pypi.replaceAll(".", "\\.")));
assert.ok(volcengine.indexOf(huawei) < volcengine.indexOf(aliyun));
assert.ok(volcengine.indexOf(aliyun) < volcengine.indexOf(pypi));
assert.match(byteplus, /RUN uv pip install -r requirements\.txt/);
assert.doesNotMatch(byteplus, /repo\.huaweicloud\.com|mirrors\.aliyun\.com/);
});

test("exports cloud environment selections through YAML", () => {
Expand Down
34 changes: 19 additions & 15 deletions tests/cli/test_generated_agent_backend_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def test_minimal_codegen_agent_py_compiles(tmp_path) -> None:
file.content for file in project.files if file.path == "requirements.txt"
)
assert requirements == (
"veadk-python==1.1.7\n"
"veadk-python==1.1.9\n"
"agentkit-sdk-python==0.8.4\n"
"google-adk==2.1.0\n"
"starlette==0.52.1\n"
Expand Down Expand Up @@ -130,14 +130,12 @@ def test_quick_mode_codegen_adds_dynamic_agent_toolset_and_managed_rules() -> No
assert "create_agents" in agent_py
assert "handoff_to" in agent_py
assert "'dynamicAgentDelegation': True" in agent_py
assert "veadk-python==1.1.7\n" in requirements
assert "veadk-python==1.1.9\n" in requirements
assert "github.com/volcengine/veadk-python" not in requirements
assert "RUN uv pip install -r requirements.txt || \\" in dockerfile
assert (
"uv pip install --index-url "
"https://repo.huaweicloud.com/repository/pypi/simple -r requirements.txt"
in dockerfile
)
huawei = "https://repo.huaweicloud.com/repository/pypi/simple"
aliyun = "https://mirrors.aliyun.com/pypi/simple/"
pypi = "https://pypi.org/simple"
assert dockerfile.index(huawei) < dockerfile.index(aliyun) < dockerfile.index(pypi)

compat_py = next(
file.content
Expand Down Expand Up @@ -757,7 +755,7 @@ def test_traditional_codegen_does_not_add_dynamic_agent_capability() -> None:
assert "CreateAgentToolset" not in agent_py
assert "动态子智能体协作规则" not in agent_py
assert "dynamicAgentDelegation" not in agent_py
assert "veadk-python==1.1.7" in requirements
assert "veadk-python==1.1.9" in requirements


def test_codegen_environment_image_adds_skills_without_replacing_agent_skills() -> None:
Expand Down Expand Up @@ -923,12 +921,18 @@ def test_codegen_cloud_environment_uses_provider_base_image(
in files["Dockerfile"]
)
assert 'CMD ["python", "-m", "app"]' in files["Dockerfile"]
assert "RUN uv pip install -r requirements.txt || \\" in files["Dockerfile"]
assert (
"uv pip install --index-url "
"https://repo.huaweicloud.com/repository/pypi/simple -r requirements.txt"
in files["Dockerfile"]
)
dockerfile = files["Dockerfile"]
if cloud_provider == "volcengine":
huawei = "https://repo.huaweicloud.com/repository/pypi/simple"
aliyun = "https://mirrors.aliyun.com/pypi/simple/"
pypi = "https://pypi.org/simple"
assert (
dockerfile.index(huawei) < dockerfile.index(aliyun) < dockerfile.index(pypi)
)
else:
assert "RUN uv pip install -r requirements.txt" in dockerfile
assert "repo.huaweicloud.com" not in dockerfile
assert "mirrors.aliyun.com" not in dockerfile


def test_codegen_cloud_environment_installs_github_cli_for_both_architectures() -> None:
Expand Down
4 changes: 2 additions & 2 deletions tests/cli/test_generated_agent_backend_codegen_extended.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"agents/demo_agent/__init__.py": "ba3abbb199bbae74dc75151a44ba53a557e5f47d509835950ca756346c5a9582",
"agents/demo_agent/dynamic_a2a.py": "d136f27d6a77439708c415686a3d167f2ad2fb9a96a5f8a0751916b09d46e364",
".env.example": "ec3258da9bef4e74333376d8554c265ccb12a4a1e5d4e1e1b0acdf5c9ae93ab6",
"requirements.txt": "33054921190810d876ac568ff102f3f42e15d85657f01a033598fc4f50994db4",
"requirements.txt": "a66e74d4c0b91cc4cc036f6026599a787056ea72a034d857bedd92fddc6d779f",
"README.md": "a34208314cf9061c02662028d7a9dd97448e6b73c1d732cb4aeaa8f70dbbc684",
}

Expand All @@ -86,7 +86,7 @@
"agents/full_agent/__init__.py": "ba3abbb199bbae74dc75151a44ba53a557e5f47d509835950ca756346c5a9582",
"agents/full_agent/dynamic_a2a.py": "d136f27d6a77439708c415686a3d167f2ad2fb9a96a5f8a0751916b09d46e364",
".env.example": "2bfd3afda4e661fbb71588ec5f0d584ce6682363cacc81b0394f8da09f7977e8",
"requirements.txt": "ee61f1353a4ac0771229b38afb1e2983c8f77ddfe0b0b2dfbe22767376668654",
"requirements.txt": "63eb2d042226abfb78238725727c6a13724472a1f55d84d55f3fa79cd07be9eb",
"README.md": "1bf4dc889c7d1076f50784d253b53412ba7c49bcb69a5d948f9092dbbecb18ac",
}

Expand Down
4 changes: 2 additions & 2 deletions tests/cli/test_generated_agent_component_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def _assert_python_files_compile(project: GeneratedProject) -> None:

def _veadk_requirement(extras: set[str]) -> str:
extras_str = f"[{','.join(sorted(extras))}]" if extras else ""
return f"veadk-python{extras_str}==1.1.7"
return f"veadk-python{extras_str}==1.1.9"


EXPECTED_LTM_EXTRAS = {
Expand Down Expand Up @@ -778,5 +778,5 @@ def test_deeply_nested_agent_types_generate_complete_component_project() -> None
assert 'KnowledgeBase(backend="context_search"' in agent_py
assert "OpentelemetryTracer()" in agent_py
assert _env_keys(files[".env.example"]) == expected_env
assert "veadk-python[extensions]==1.1.7" in files["requirements.txt"]
assert "veadk-python[extensions]==1.1.9" in files["requirements.txt"]
_assert_python_files_compile(project)
30 changes: 21 additions & 9 deletions veadk/cli/generated_agent_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@
"volcengine": "agentkit-prod-public-cn-beijing.cr.volces.com/base/py-simple:python3.12-bookworm-slim-latest",
"byteplus": "agentkit-prod-public-ap-southeast-1.cr.bytepluses.com/base/py-simple:python3.12-bookworm-slim-latest",
}
_PYPI_FALLBACK_INDEX = "https://repo.huaweicloud.com/repository/pypi/simple"
_VEADK_VERSION = "1.1.9"
_VOLCENGINE_PYPI_INDEXES = (
"https://repo.huaweicloud.com/repository/pypi/simple",
"https://mirrors.aliyun.com/pypi/simple/",
"https://pypi.org/simple",
)
_LARK_CLI_VERSION = "1.0.87"
_LARK_CLI_SHA256 = {
"amd64": "6027b1ddc12440400581bbdf9554850d8e119c7dd400439b1220e7a87b9673c5",
Expand Down Expand Up @@ -1060,7 +1065,7 @@ def render_requirements(
unique_extras = sorted(all_extras)
extras_str = f"[{','.join(unique_extras)}]" if unique_extras else ""
managed_sidecar = "harness-sidecar" in all_extras
pkg = f"veadk-python{extras_str}==1.1.7"
pkg = f"veadk-python{extras_str}=={_VEADK_VERSION}"
agentkit_sdk = (
"agentkit-sdk-python==0.8.1"
if managed_sidecar
Expand Down Expand Up @@ -1239,7 +1244,7 @@ def _render_managed_main_py() -> str:


def _render_quick_mode_compat_py() -> str:
"""Backport quick-mode runtime behavior while deployments stay on 1.1.7."""
"""Keep quick-mode runtime behavior available in the pinned runtime."""

create_agents_schema = pformat(
CreateAgentsInput.model_json_schema(by_alias=True),
Expand Down Expand Up @@ -1412,7 +1417,7 @@ def _get_declaration(self) -> types.FunctionDeclaration | None:


class CreateAgentToolset(_BaseCreateAgentToolset):
"""Keep quick-mode semantics available in the pinned 1.1.7 runtime."""
"""Keep quick-mode semantics available in the pinned runtime."""

_MAX_COMPLETED_CREATIONS = 128

Expand Down Expand Up @@ -2144,6 +2149,17 @@ def _github_release_urls(cloud_provider: str, repository: str) -> list[str]:
return [mirror, official] if cloud_provider == "volcengine" else [official, mirror]


def _render_python_dependency_install(cloud_provider: str) -> str:
if cloud_provider != "volcengine":
return "RUN uv pip install -r requirements.txt"

attempts = [
f"uv pip install --index-url {index} -r requirements.txt"
for index in _VOLCENGINE_PYPI_INDEXES
]
return "RUN " + " || \\\n ".join(attempts)


def render_cloud_environment_dockerfile(draft: AgentDraft) -> str | None:
"""Render the custom image or an AgentKit-compatible image for selected CLIs."""
if draft.cloudEnvironment.resolvedImage:
Expand Down Expand Up @@ -2232,11 +2248,7 @@ def render_cloud_environment_dockerfile(draft: AgentDraft) -> str | None:
"",
"# Install Python dependencies before copying the source for better layer caching.",
"COPY requirements.txt requirements.txt",
(
"RUN uv pip install -r requirements.txt || \\\n"
f" uv pip install --index-url {_PYPI_FALLBACK_INDEX} "
"-r requirements.txt"
),
_render_python_dependency_install(draft.cloudProvider),
"",
"# Copy the Agent application and configure its runtime entrypoint.",
"EXPOSE 8000",
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Loading
Loading