diff --git a/LICENSE b/LICENSE index 41fe2b9..7a4a3ea 100644 --- a/LICENSE +++ b/LICENSE @@ -187,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2026 Huawei Technologies Co., Ltd. All rights reserved. + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -199,4 +199,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. + limitations under the License. \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index dfc7812..4f2d3fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "uv_build" [project] name = "agentarts-sdk" -version = "0.1.1" +version = "0.1.2" description = "Huawei Cloud AgentArts SDK - Build, deploy and manage AI agents with cloud capabilities" readme = "README.md" license = {file = "LICENSE"} diff --git a/src/agentarts/sdk/service/runtime_client.py b/src/agentarts/sdk/service/runtime_client.py index 9147516..bbe8e78 100644 --- a/src/agentarts/sdk/service/runtime_client.py +++ b/src/agentarts/sdk/service/runtime_client.py @@ -650,7 +650,7 @@ def invoke_agent( """ from agentarts.sdk.runtime.model import SESSION_HEADER, USER_ID_HEADER - path = f"/agent/{agent_name}/invocations" + path = f"/runtimes/{agent_name}/invocations" params: dict[str, Any] = {} if endpoint: params["endpoint"] = endpoint @@ -721,7 +721,7 @@ def ping_agent( result = self._data( "GET", - f"/agent/{agent_name}/ping", + f"/runtimes/{agent_name}/ping", params=params if params else None, headers=headers if headers else None, timeout=timeout, diff --git a/src/agentarts/sdk/service/swr_client.py b/src/agentarts/sdk/service/swr_client.py index d5e6f26..d18a0b6 100644 --- a/src/agentarts/sdk/service/swr_client.py +++ b/src/agentarts/sdk/service/swr_client.py @@ -158,7 +158,7 @@ def get_organization(self, organization: str) -> dict[str, Any] | None: } except Exception as e: - print(f"Organization '{organization}' not found: {e}") + print(f"Organization '{organization}' query failed: {e}") return None def create_organization( @@ -253,7 +253,7 @@ def get_repository( } except Exception as e: - print(f"Repository '{organization}/{repository}' not found: {e}") + print(f"Repository '{organization}/{repository}' query failed: {e}") return None def create_repository( diff --git a/src/agentarts/toolkit/cli/runtime/config.py b/src/agentarts/toolkit/cli/runtime/config.py index ae436cc..094cfcf 100644 --- a/src/agentarts/toolkit/cli/runtime/config.py +++ b/src/agentarts/toolkit/cli/runtime/config.py @@ -12,6 +12,7 @@ echo_info, echo_success, ) +from agentarts.toolkit.utils.swr_org import generate_swr_org_name console = Console() @@ -111,7 +112,7 @@ def main( if org is None: existing_config = config_op.get_agent(agent_name) default_org = existing_config.swr_config.organization if existing_config else None - auto_org = "agentarts-org" + auto_org = generate_swr_org_name(region=agent_region) console.print("\n[bold]SWR Organization:[/bold]") if default_org: diff --git a/src/agentarts/toolkit/cli/runtime/init.py b/src/agentarts/toolkit/cli/runtime/init.py index d816913..9ee1c3c 100644 --- a/src/agentarts/toolkit/cli/runtime/init.py +++ b/src/agentarts/toolkit/cli/runtime/init.py @@ -8,6 +8,7 @@ from rich.prompt import Prompt from agentarts.toolkit.operations.runtime import init as init_op +from agentarts.toolkit.utils.swr_org import generate_default_agent_name console = Console() @@ -53,7 +54,8 @@ def prompt_for_template() -> TemplateType: def prompt_for_name() -> str: """Prompt user to enter project name""" - return Prompt.ask("\n[bold]Enter project name[/bold]", default="myagent") + default_name = generate_default_agent_name() + return Prompt.ask("\n[bold]Enter project name[/bold]", default=default_name) def prompt_for_region() -> str: @@ -83,7 +85,7 @@ def init( ] = None, swr_org: Annotated[ str | None, - typer.Option("--swr-org", help="SWR organization (default: agentarts-org)"), + typer.Option("--swr-org", help="SWR organization (auto-generated if not specified)"), ] = None, swr_repo: Annotated[ str | None, diff --git a/src/agentarts/toolkit/operations/runtime/config.py b/src/agentarts/toolkit/operations/runtime/config.py index 4f80146..adba42c 100644 --- a/src/agentarts/toolkit/operations/runtime/config.py +++ b/src/agentarts/toolkit/operations/runtime/config.py @@ -12,6 +12,7 @@ BaseConfig, SWRConfig, ) +from agentarts.toolkit.utils.swr_org import generate_swr_org_name console = Console() @@ -227,7 +228,8 @@ def add_agent( existing_dict.setdefault("swr_config", {})["repository_auto_create"] = repository_auto_create final_region = existing_dict.get("base", {}).get("region", "cn-southwest-2") - final_org = existing_dict.get("swr_config", {}).get("organization", "agentarts-org") + existing_org = existing_dict.get("swr_config", {}).get("organization") + final_org = existing_org or generate_swr_org_name(region=final_region) final_repo = existing_dict.get("swr_config", {}).get("repository", f"agent_{name}") artifact_url = f"swr.{final_region}.myhuaweicloud.com/{final_org}/{final_repo}:latest" @@ -253,7 +255,7 @@ def add_agent( ) final_region = region or "cn-southwest-2" - final_org = swr_organization or "agentarts-org" + final_org = swr_organization or generate_swr_org_name(region=final_region) final_repo = swr_repository or f"agent_{name}" artifact_url = f"swr.{final_region}.myhuaweicloud.com/{final_org}/{final_repo}:latest" diff --git a/src/agentarts/toolkit/operations/runtime/init.py b/src/agentarts/toolkit/operations/runtime/init.py index d103efa..511b55a 100644 --- a/src/agentarts/toolkit/operations/runtime/init.py +++ b/src/agentarts/toolkit/operations/runtime/init.py @@ -11,6 +11,7 @@ echo_step, echo_success, ) +from agentarts.toolkit.utils.swr_org import generate_swr_org_name from agentarts.toolkit.utils.templates.manager import template_manager console = Console() @@ -148,7 +149,7 @@ def create_config_file( ) -> None: """Create .agentarts_config.yaml configuration file.""" actual_region = region or "cn-southwest-2" - actual_swr_org = swr_org or "agentarts-org" + actual_swr_org = swr_org or generate_swr_org_name(region=actual_region) actual_swr_repo = swr_repo or f"agent_{name}" detected_platform = detect_platform() diff --git a/src/agentarts/toolkit/utils/swr_org.py b/src/agentarts/toolkit/utils/swr_org.py new file mode 100644 index 0000000..a87c804 --- /dev/null +++ b/src/agentarts/toolkit/utils/swr_org.py @@ -0,0 +1,141 @@ +"""SWR organization name generator.""" + +import hashlib +import random +import string + +from agentarts.sdk.utils.constant import get_ak + + +def shorten_region(region: str) -> str: + """ + Shorten region name to a compact form. + + Examples: + cn-southwest-2 -> cnsw2 + cn-north-4 -> cnno4 + ap-southeast-1 -> apse1 + + Args: + region: Full region name (e.g., 'cn-southwest-2') + + Returns: + Shortened region name (max 6 chars) + """ + parts = region.split("-") + if len(parts) >= 3: + provider = parts[0][:2] + area = parts[1][:2] + num = parts[2] if len(parts) > 2 else "" + if len(num) > 2: + num = num[:2] + return f"{provider}{area}{num}" + return region.replace("-", "")[:6] + + +def generate_ak_identifier(ak: str | None = None, length: int = 8) -> str: + """ + Generate identifier from AK (Access Key). + + If AK is available, uses hash of AK to generate consistent identifier. + If AK is not available, generates random identifier. + + Args: + ak: Access Key string. If None, will try to get from environment. + length: Length of identifier to generate (default 8) + + Returns: + Identifier string of specified length + """ + if ak is None: + ak = get_ak() + + if ak and len(ak) > 0: + hash_obj = hashlib.md5(ak.encode(), usedforsecurity=False) + hash_hex = hash_obj.hexdigest() + return hash_hex[:length].lower() + + chars = string.ascii_lowercase + string.digits + return "".join(random.choices(chars, k=length)) + + +def generate_random_suffix(length: int = 6) -> str: + """ + Generate random suffix for uniqueness. + + Args: + length: Length of random suffix (default 6) + + Returns: + Random string of lowercase letters and digits + """ + chars = string.ascii_lowercase + string.digits + return "".join(random.choices(chars, k=length)) + + +def generate_default_agent_name(base_name: str = "myagent", suffix_length: int = 5) -> str: + """ + Generate default agent name with random suffix. + + Args: + base_name: Base name for the agent (default: 'myagent') + suffix_length: Length of random suffix (default 5) + + Returns: + Agent name with random suffix (e.g., 'myagent-abc12') + """ + suffix = generate_random_suffix(suffix_length) + return f"{base_name}-{suffix}" + + +def generate_swr_org_name( + region: str | None = None, + ak: str | None = None, + max_length: int = 64, +) -> str: + """ + Generate unique SWR organization name. + + Format: agentarts-{region_short}-{ak_identifier}-org + + The generated name is designed to be: + 1. Unique per account (based on AK hash) + 2. Consistent per account (same AK generates same name) + 3. Within max_length constraint (default 64 chars) + + Args: + region: Huawei Cloud region (e.g., 'cn-southwest-2') + If None, uses 'default' as placeholder + ak: Access Key for account identification + If None, will try to get from environment + max_length: Maximum length of organization name (default 64) + + Returns: + Unique SWR organization name + + Examples: + >>> generate_swr_org_name("cn-southwest-2", "ABCDEFGHIJKLMNOP") + 'agentarts-cnso2-19fc8eff-org' + + >>> generate_swr_org_name("cn-southwest-2") # AK from env + 'agentarts-cnso2--org' + """ + prefix = "agentarts-" + suffix = "-org" + + region_short = shorten_region(region or "default") + + ak_identifier = generate_ak_identifier(ak, length=8) + + base_name = f"{prefix}{region_short}-{ak_identifier}{suffix}" + + if len(base_name) > max_length: + excess = len(base_name) - max_length + ak_identifier = generate_ak_identifier(ak, length=8 - min(excess, 8)) + base_name = f"{prefix}{region_short}-{ak_identifier}{suffix}" + + if len(base_name) > max_length: + region_short = region_short[: len(region_short) - min(len(base_name) - max_length, len(region_short))] + base_name = f"{prefix}{region_short}{suffix}" + + return base_name.lower()