agentscope-runtime 1.0.4__py3-none-any.whl → 1.0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentscope_runtime/adapters/agentscope/stream.py +1 -1
- agentscope_runtime/adapters/langgraph/stream.py +120 -70
- agentscope_runtime/cli/commands/deploy.py +465 -1
- agentscope_runtime/cli/commands/stop.py +16 -0
- agentscope_runtime/common/container_clients/__init__.py +52 -0
- agentscope_runtime/common/container_clients/agentrun_client.py +6 -4
- agentscope_runtime/common/container_clients/boxlite_client.py +442 -0
- agentscope_runtime/common/container_clients/docker_client.py +0 -20
- agentscope_runtime/common/container_clients/fc_client.py +6 -4
- agentscope_runtime/common/container_clients/gvisor_client.py +38 -0
- agentscope_runtime/common/container_clients/knative_client.py +1 -0
- agentscope_runtime/common/utils/deprecation.py +164 -0
- agentscope_runtime/engine/app/agent_app.py +16 -4
- agentscope_runtime/engine/deployers/__init__.py +31 -20
- agentscope_runtime/engine/deployers/adapter/__init__.py +8 -0
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +9 -8
- agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +19 -1
- agentscope_runtime/engine/deployers/adapter/agui/__init__.py +8 -0
- agentscope_runtime/engine/deployers/adapter/agui/agui_adapter_utils.py +652 -0
- agentscope_runtime/engine/deployers/adapter/agui/agui_protocol_adapter.py +225 -0
- agentscope_runtime/engine/deployers/pai_deployer.py +2335 -0
- agentscope_runtime/engine/deployers/utils/net_utils.py +37 -0
- agentscope_runtime/engine/deployers/utils/oss_utils.py +38 -0
- agentscope_runtime/engine/deployers/utils/package.py +46 -42
- agentscope_runtime/engine/helpers/agent_api_client.py +372 -0
- agentscope_runtime/engine/runner.py +1 -0
- agentscope_runtime/engine/schemas/agent_schemas.py +9 -3
- agentscope_runtime/engine/services/agent_state/__init__.py +7 -0
- agentscope_runtime/engine/services/memory/__init__.py +7 -0
- agentscope_runtime/engine/services/memory/redis_memory_service.py +15 -16
- agentscope_runtime/engine/services/session_history/__init__.py +7 -0
- agentscope_runtime/engine/tracing/local_logging_handler.py +2 -3
- agentscope_runtime/sandbox/box/sandbox.py +4 -0
- agentscope_runtime/sandbox/manager/sandbox_manager.py +11 -25
- agentscope_runtime/sandbox/manager/server/config.py +3 -1
- agentscope_runtime/sandbox/model/manager_config.py +11 -9
- agentscope_runtime/tools/modelstudio_memory/__init__.py +106 -0
- agentscope_runtime/tools/modelstudio_memory/base.py +220 -0
- agentscope_runtime/tools/modelstudio_memory/config.py +86 -0
- agentscope_runtime/tools/modelstudio_memory/core.py +594 -0
- agentscope_runtime/tools/modelstudio_memory/exceptions.py +60 -0
- agentscope_runtime/tools/modelstudio_memory/schemas.py +253 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/METADATA +101 -62
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/RECORD +49 -34
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/WHEEL +0 -0
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/entry_points.txt +0 -0
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""agentscope deploy command - Deploy agents to various platforms."""
|
|
3
3
|
# pylint: disable=too-many-statements, too-many-branches
|
|
4
|
+
# pylint: disable=too-many-nested-blocks
|
|
4
5
|
|
|
5
6
|
import asyncio
|
|
6
7
|
import json
|
|
7
8
|
import os
|
|
8
9
|
import sys
|
|
10
|
+
from typing import Optional
|
|
9
11
|
|
|
10
12
|
import click
|
|
11
13
|
import yaml
|
|
@@ -65,6 +67,17 @@ try:
|
|
|
65
67
|
except ImportError:
|
|
66
68
|
KNATIVE_AVAILABLE = False
|
|
67
69
|
|
|
70
|
+
try:
|
|
71
|
+
from agentscope_runtime.engine.deployers.pai_deployer import (
|
|
72
|
+
PAI_AVAILABLE,
|
|
73
|
+
PAIDeployConfig,
|
|
74
|
+
PAIDeployManager,
|
|
75
|
+
)
|
|
76
|
+
except ImportError:
|
|
77
|
+
PAI_AVAILABLE = False
|
|
78
|
+
PAIDeployConfig = None
|
|
79
|
+
PAIDeployManager = None
|
|
80
|
+
|
|
68
81
|
|
|
69
82
|
def _validate_source(source: str) -> tuple[str, str]:
|
|
70
83
|
"""
|
|
@@ -90,7 +103,10 @@ def _validate_source(source: str) -> tuple[str, str]:
|
|
|
90
103
|
raise ValueError(f"Source must be a file or directory: {abs_source}")
|
|
91
104
|
|
|
92
105
|
|
|
93
|
-
def _find_entrypoint(
|
|
106
|
+
def _find_entrypoint(
|
|
107
|
+
project_dir: str,
|
|
108
|
+
entrypoint: Optional[str] = None,
|
|
109
|
+
) -> str:
|
|
94
110
|
"""
|
|
95
111
|
Find or validate entrypoint file in project directory.
|
|
96
112
|
|
|
@@ -185,6 +201,33 @@ def _merge_config(config_dict: dict, cli_params: dict) -> dict:
|
|
|
185
201
|
return merged
|
|
186
202
|
|
|
187
203
|
|
|
204
|
+
def _parse_tags(tag_tuples: tuple) -> dict:
|
|
205
|
+
"""
|
|
206
|
+
Parse tags from --tag options.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
tag_tuples: Tuple of KEY=VALUE strings from --tag options
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
Dictionary of tags
|
|
213
|
+
|
|
214
|
+
Raises:
|
|
215
|
+
ValueError: If tag format is invalid
|
|
216
|
+
"""
|
|
217
|
+
tags = {}
|
|
218
|
+
|
|
219
|
+
for tag_pair in tag_tuples:
|
|
220
|
+
if "=" not in tag_pair:
|
|
221
|
+
raise ValueError(
|
|
222
|
+
f"Invalid tag format: '{tag_pair}'. Use KEY=VALUE format",
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
key, value = tag_pair.split("=", 1)
|
|
226
|
+
tags[key.strip()] = value.strip()
|
|
227
|
+
|
|
228
|
+
return tags
|
|
229
|
+
|
|
230
|
+
|
|
188
231
|
def _parse_environment(env_tuples: tuple, env_file: str = None) -> dict:
|
|
189
232
|
"""
|
|
190
233
|
Parse environment variables from --env options and --env-file.
|
|
@@ -254,6 +297,7 @@ def deploy():
|
|
|
254
297
|
\b
|
|
255
298
|
- modelstudio: Alibaba Cloud ModelStudio
|
|
256
299
|
- agentrun: Alibaba Cloud AgentRun
|
|
300
|
+
- pai: Alibaba Cloud PAI (Platform for AI)
|
|
257
301
|
- k8s: Kubernetes/ACK
|
|
258
302
|
- local: Local deployment (detached mode)
|
|
259
303
|
- Knative: Knative/ACK Knative
|
|
@@ -711,6 +755,426 @@ def agentrun(
|
|
|
711
755
|
sys.exit(1)
|
|
712
756
|
|
|
713
757
|
|
|
758
|
+
@deploy.command()
|
|
759
|
+
@click.argument("source", required=False, default=None)
|
|
760
|
+
@click.option(
|
|
761
|
+
"--config",
|
|
762
|
+
"-c",
|
|
763
|
+
type=click.Path(exists=True),
|
|
764
|
+
help="Path to deployment config file (.yaml or .yml). "
|
|
765
|
+
"See pai_deploy_config.yaml for example.",
|
|
766
|
+
)
|
|
767
|
+
@click.option("--name", help="Service name (required)", default=None)
|
|
768
|
+
@click.option(
|
|
769
|
+
"--workspace-id",
|
|
770
|
+
help="PAI workspace ID (or PAI_WORKSPACE_ID env var)",
|
|
771
|
+
default=None,
|
|
772
|
+
)
|
|
773
|
+
@click.option(
|
|
774
|
+
"--region",
|
|
775
|
+
help="Region ID (e.g., cn-hangzhou)",
|
|
776
|
+
default=None,
|
|
777
|
+
)
|
|
778
|
+
@click.option(
|
|
779
|
+
"--entrypoint",
|
|
780
|
+
help="Entrypoint file name (default: app.py, agent.py, or main.py)",
|
|
781
|
+
default=None,
|
|
782
|
+
)
|
|
783
|
+
@click.option(
|
|
784
|
+
"--oss-path",
|
|
785
|
+
help="OSS work directory (e.g., oss://bucket/path/)",
|
|
786
|
+
default=None,
|
|
787
|
+
)
|
|
788
|
+
@click.option(
|
|
789
|
+
"--instance-type",
|
|
790
|
+
help="Instance type for public resource (e.g., ecs.c6.large)",
|
|
791
|
+
default=None,
|
|
792
|
+
)
|
|
793
|
+
@click.option(
|
|
794
|
+
"--instance-count",
|
|
795
|
+
help="Number of instances",
|
|
796
|
+
type=int,
|
|
797
|
+
default=None,
|
|
798
|
+
)
|
|
799
|
+
@click.option(
|
|
800
|
+
"--resource-id",
|
|
801
|
+
help="EAS resource group ID (for resource mode)",
|
|
802
|
+
default=None,
|
|
803
|
+
)
|
|
804
|
+
@click.option(
|
|
805
|
+
"--quota-id",
|
|
806
|
+
help="PAI quota ID (for quota mode)",
|
|
807
|
+
default=None,
|
|
808
|
+
)
|
|
809
|
+
@click.option("--cpu", help="CPU cores", type=int, default=None)
|
|
810
|
+
@click.option("--memory", help="Memory in MB", type=int, default=None)
|
|
811
|
+
@click.option("--service-group", help="Service group name", default=None)
|
|
812
|
+
@click.option(
|
|
813
|
+
"--resource-type",
|
|
814
|
+
type=click.Choice(["public", "resource", "quota"]),
|
|
815
|
+
help="Resource type: public (instance), resource (EAS group), quota",
|
|
816
|
+
default=None,
|
|
817
|
+
)
|
|
818
|
+
@click.option(
|
|
819
|
+
"--vpc-id",
|
|
820
|
+
help="VPC ID for network configuration",
|
|
821
|
+
default=None,
|
|
822
|
+
)
|
|
823
|
+
@click.option(
|
|
824
|
+
"--vswitch-id",
|
|
825
|
+
help="VSwitch ID for network configuration",
|
|
826
|
+
default=None,
|
|
827
|
+
)
|
|
828
|
+
@click.option(
|
|
829
|
+
"--security-group-id",
|
|
830
|
+
help="Security group ID for network configuration",
|
|
831
|
+
default=None,
|
|
832
|
+
)
|
|
833
|
+
@click.option("--ram-role-arn", help="RAM role ARN", default=None)
|
|
834
|
+
@click.option(
|
|
835
|
+
"--enable-trace/--no-trace",
|
|
836
|
+
help="Enable/disable tracing",
|
|
837
|
+
default=None,
|
|
838
|
+
)
|
|
839
|
+
@click.option(
|
|
840
|
+
"--wait/--no-wait",
|
|
841
|
+
help="Wait for deployment to complete",
|
|
842
|
+
default=None,
|
|
843
|
+
)
|
|
844
|
+
@click.option(
|
|
845
|
+
"--timeout",
|
|
846
|
+
help="Deployment timeout in seconds",
|
|
847
|
+
type=int,
|
|
848
|
+
default=None,
|
|
849
|
+
)
|
|
850
|
+
@click.option(
|
|
851
|
+
"--auto-approve/--no-auto-approve",
|
|
852
|
+
help="Auto approve the deployment",
|
|
853
|
+
default=None,
|
|
854
|
+
)
|
|
855
|
+
@click.option(
|
|
856
|
+
"--env",
|
|
857
|
+
"-E",
|
|
858
|
+
multiple=True,
|
|
859
|
+
help="Environment variable in KEY=VALUE format (can be repeated)",
|
|
860
|
+
)
|
|
861
|
+
@click.option(
|
|
862
|
+
"--env-file",
|
|
863
|
+
type=click.Path(exists=True),
|
|
864
|
+
help="Path to .env file with environment variables",
|
|
865
|
+
)
|
|
866
|
+
@click.option(
|
|
867
|
+
"--tag",
|
|
868
|
+
"-T",
|
|
869
|
+
multiple=True,
|
|
870
|
+
help="Tag in KEY=VALUE format (can be repeated)",
|
|
871
|
+
)
|
|
872
|
+
def pai(
|
|
873
|
+
source: str,
|
|
874
|
+
config: str,
|
|
875
|
+
name: str,
|
|
876
|
+
workspace_id: str,
|
|
877
|
+
region: str,
|
|
878
|
+
entrypoint: str,
|
|
879
|
+
oss_path: str,
|
|
880
|
+
instance_type: str,
|
|
881
|
+
instance_count: int,
|
|
882
|
+
resource_id: str,
|
|
883
|
+
quota_id: str,
|
|
884
|
+
cpu: int,
|
|
885
|
+
memory: int,
|
|
886
|
+
service_group: str,
|
|
887
|
+
resource_type: str,
|
|
888
|
+
vpc_id: str,
|
|
889
|
+
vswitch_id: str,
|
|
890
|
+
security_group_id: str,
|
|
891
|
+
ram_role_arn: str,
|
|
892
|
+
enable_trace: bool,
|
|
893
|
+
wait: bool,
|
|
894
|
+
timeout: int,
|
|
895
|
+
auto_approve: bool,
|
|
896
|
+
env: tuple,
|
|
897
|
+
env_file: str,
|
|
898
|
+
tag: tuple,
|
|
899
|
+
):
|
|
900
|
+
"""
|
|
901
|
+
Deploy to Alibaba Cloud PAI (Platform for AI).
|
|
902
|
+
|
|
903
|
+
\b
|
|
904
|
+
Usage:
|
|
905
|
+
# Using config file (recommended)
|
|
906
|
+
agentscope deploy pai --config pai_deploy_config.yaml
|
|
907
|
+
|
|
908
|
+
# Using config file with CLI overrides
|
|
909
|
+
agentscope deploy pai --config pai_deploy_config.yaml --name new-name
|
|
910
|
+
|
|
911
|
+
# Using CLI only
|
|
912
|
+
agentscope deploy pai ./my_agent --name my-service --workspace-id 12345
|
|
913
|
+
|
|
914
|
+
\b
|
|
915
|
+
Required:
|
|
916
|
+
- Service name (--name or spec.name in config)
|
|
917
|
+
- Source directory (SOURCE argument or spec.code.source_dir in config)
|
|
918
|
+
- Workspace ID (--workspace-id, context.workspace_id, or env)
|
|
919
|
+
|
|
920
|
+
\b
|
|
921
|
+
Environment variables:
|
|
922
|
+
- ALIBABA_CLOUD_ACCESS_KEY_ID
|
|
923
|
+
- ALIBABA_CLOUD_ACCESS_KEY_SECRET
|
|
924
|
+
- PAI_WORKSPACE_ID (optional if --workspace-id provided)
|
|
925
|
+
- REGION_ID or ALIBABA_CLOUD_REGION_ID (optional)
|
|
926
|
+
"""
|
|
927
|
+
if not PAI_AVAILABLE:
|
|
928
|
+
echo_error("PAI deployer is not available")
|
|
929
|
+
echo_info(
|
|
930
|
+
"Please install required dependencies via "
|
|
931
|
+
"pip install 'agentscope-runtime[ext]'",
|
|
932
|
+
)
|
|
933
|
+
sys.exit(1)
|
|
934
|
+
|
|
935
|
+
try:
|
|
936
|
+
# Step 1: Build configuration from config file or defaults
|
|
937
|
+
if config:
|
|
938
|
+
echo_info(f"Loading configuration from {config}...")
|
|
939
|
+
deploy_config = PAIDeployConfig.from_yaml(config)
|
|
940
|
+
else:
|
|
941
|
+
deploy_config = PAIDeployConfig()
|
|
942
|
+
|
|
943
|
+
# Step 2: Parse CLI environment variables and tags
|
|
944
|
+
cli_env = _parse_environment(env, env_file)
|
|
945
|
+
cli_tags = _parse_tags(tag)
|
|
946
|
+
|
|
947
|
+
# Step 3: Resolve source path
|
|
948
|
+
resolved_source = None
|
|
949
|
+
if source:
|
|
950
|
+
abs_source, source_type = _validate_source(source)
|
|
951
|
+
if source_type == "file":
|
|
952
|
+
# For single file: use parent directory as project_dir
|
|
953
|
+
resolved_source = os.path.dirname(abs_source)
|
|
954
|
+
if not entrypoint:
|
|
955
|
+
entrypoint = os.path.basename(abs_source)
|
|
956
|
+
else:
|
|
957
|
+
resolved_source = abs_source
|
|
958
|
+
|
|
959
|
+
# Step 4: Merge CLI parameters (CLI takes precedence)
|
|
960
|
+
deploy_config = deploy_config.merge_cli(
|
|
961
|
+
source=resolved_source,
|
|
962
|
+
name=name,
|
|
963
|
+
entrypoint=entrypoint,
|
|
964
|
+
workspace_id=workspace_id,
|
|
965
|
+
region=region,
|
|
966
|
+
oss_path=oss_path,
|
|
967
|
+
instance_type=instance_type,
|
|
968
|
+
instance_count=instance_count,
|
|
969
|
+
resource_id=resource_id,
|
|
970
|
+
quota_id=quota_id,
|
|
971
|
+
cpu=cpu,
|
|
972
|
+
memory=memory,
|
|
973
|
+
service_group=service_group,
|
|
974
|
+
resource_type=resource_type,
|
|
975
|
+
vpc_id=vpc_id,
|
|
976
|
+
vswitch_id=vswitch_id,
|
|
977
|
+
security_group_id=security_group_id,
|
|
978
|
+
ram_role_arn=ram_role_arn,
|
|
979
|
+
enable_trace=enable_trace,
|
|
980
|
+
wait=wait,
|
|
981
|
+
timeout=timeout,
|
|
982
|
+
auto_approve=auto_approve,
|
|
983
|
+
environment=cli_env if cli_env else None,
|
|
984
|
+
tags=cli_tags if cli_tags else None,
|
|
985
|
+
)
|
|
986
|
+
|
|
987
|
+
# Step 5: Resolve source_dir to absolute path
|
|
988
|
+
if deploy_config.spec.code.source_dir:
|
|
989
|
+
source_dir = deploy_config.spec.code.source_dir
|
|
990
|
+
if not os.path.isabs(source_dir):
|
|
991
|
+
# If config file provided, resolve relative to config file dir
|
|
992
|
+
if config:
|
|
993
|
+
base_dir = os.path.dirname(os.path.abspath(config))
|
|
994
|
+
source_dir = os.path.join(base_dir, source_dir)
|
|
995
|
+
else:
|
|
996
|
+
source_dir = os.path.abspath(source_dir)
|
|
997
|
+
# Update with resolved path
|
|
998
|
+
deploy_config.spec.code.source_dir = source_dir
|
|
999
|
+
|
|
1000
|
+
# Step 6: Find entrypoint if not specified
|
|
1001
|
+
if (
|
|
1002
|
+
deploy_config.spec.code.source_dir
|
|
1003
|
+
and not deploy_config.spec.code.entrypoint
|
|
1004
|
+
):
|
|
1005
|
+
entry_script = _find_entrypoint(
|
|
1006
|
+
deploy_config.spec.code.source_dir,
|
|
1007
|
+
)
|
|
1008
|
+
deploy_config.spec.code.entrypoint = entry_script
|
|
1009
|
+
|
|
1010
|
+
# Step 7: Validate configuration
|
|
1011
|
+
try:
|
|
1012
|
+
deploy_config.validate_for_deploy()
|
|
1013
|
+
except ValueError as e:
|
|
1014
|
+
echo_error(str(e))
|
|
1015
|
+
sys.exit(1)
|
|
1016
|
+
|
|
1017
|
+
# Step 8: Create deployer
|
|
1018
|
+
# Use resolved OSS work dir (spec.storage -> context.storage fallback)
|
|
1019
|
+
resolved_oss_path = deploy_config.resolve_oss_work_dir()
|
|
1020
|
+
deployer = PAIDeployManager(
|
|
1021
|
+
workspace_id=deploy_config.context.workspace_id,
|
|
1022
|
+
region_id=deploy_config.context.region,
|
|
1023
|
+
oss_path=resolved_oss_path,
|
|
1024
|
+
)
|
|
1025
|
+
|
|
1026
|
+
# Validate workspace_id (may come from env var in deployer)
|
|
1027
|
+
if not deployer.workspace_id:
|
|
1028
|
+
echo_error(
|
|
1029
|
+
"PAI workspace ID is required. Set PAI_WORKSPACE_ID "
|
|
1030
|
+
"environment variable, use --workspace-id, or set "
|
|
1031
|
+
"context.workspace_id in config file.",
|
|
1032
|
+
)
|
|
1033
|
+
sys.exit(1)
|
|
1034
|
+
|
|
1035
|
+
# Step 9: Display deployment info
|
|
1036
|
+
service_name = deploy_config.spec.name
|
|
1037
|
+
resource_type = deploy_config.resolve_resource_type()
|
|
1038
|
+
|
|
1039
|
+
echo_info(f"Service Name: {service_name}")
|
|
1040
|
+
echo_info(f"Workspace ID: {deployer.workspace_id}")
|
|
1041
|
+
echo_info(f"Region: {deployer.region_id}")
|
|
1042
|
+
echo_info(f"Resource Type: {resource_type}")
|
|
1043
|
+
echo_info(f"Source: {deploy_config.spec.code.source_dir}")
|
|
1044
|
+
if deploy_config.spec.code.entrypoint:
|
|
1045
|
+
echo_info(f"Entrypoint: {deploy_config.spec.code.entrypoint}")
|
|
1046
|
+
if deployer.oss_path:
|
|
1047
|
+
echo_info(f"OSS Path: {deployer.oss_path}")
|
|
1048
|
+
if deploy_config.spec.tags:
|
|
1049
|
+
echo_info(f"Tags: {deploy_config.spec.tags}")
|
|
1050
|
+
|
|
1051
|
+
# Step 10: Deploy
|
|
1052
|
+
echo_info(f"Deploying to PAI as service '{service_name}'...")
|
|
1053
|
+
|
|
1054
|
+
deploy_kwargs = deploy_config.to_deployer_kwargs()
|
|
1055
|
+
# Add deploy_method to indicate this is a CLI deployment
|
|
1056
|
+
deploy_kwargs["deploy_method"] = "cli"
|
|
1057
|
+
result = asyncio.run(deployer.deploy(**deploy_kwargs))
|
|
1058
|
+
|
|
1059
|
+
# Step 11: Display results
|
|
1060
|
+
deploy_id = result.get("deploy_id")
|
|
1061
|
+
flow_id = result.get("flow_id")
|
|
1062
|
+
snapshot_id = result.get("snapshot_id")
|
|
1063
|
+
console_url = result.get("url")
|
|
1064
|
+
status = result.get("status")
|
|
1065
|
+
|
|
1066
|
+
echo_success("Deployment created!")
|
|
1067
|
+
echo_info(f"Deployment ID: {deploy_id}")
|
|
1068
|
+
echo_info(f"Project ID: {flow_id}")
|
|
1069
|
+
echo_info(f"Snapshot ID: {snapshot_id}")
|
|
1070
|
+
echo_info(f"Service Name: {service_name}")
|
|
1071
|
+
echo_info(f"Status: {status}")
|
|
1072
|
+
echo_info(f"Deployment Console URL: {console_url}")
|
|
1073
|
+
|
|
1074
|
+
# Step 12: Handle approval flow for auto_approve=False
|
|
1075
|
+
if not deploy_config.auto_approve:
|
|
1076
|
+
# Interactive approval flow
|
|
1077
|
+
echo_info("\n" + "=" * 60)
|
|
1078
|
+
echo_warning(
|
|
1079
|
+
"Deployment created but waiting for approval.",
|
|
1080
|
+
)
|
|
1081
|
+
echo_info(
|
|
1082
|
+
f"View deployment details at:\n {console_url}",
|
|
1083
|
+
)
|
|
1084
|
+
echo_info("=" * 60)
|
|
1085
|
+
|
|
1086
|
+
# Check if we're in an interactive terminal
|
|
1087
|
+
if sys.stdin.isatty():
|
|
1088
|
+
echo_info("\nWhat would you like to do?")
|
|
1089
|
+
echo_info(" [A]pprove - Approve and start deployment")
|
|
1090
|
+
echo_info(" [C]ancel - Cancel this deployment")
|
|
1091
|
+
echo_info(" [S]kip - Skip (approve later in console)")
|
|
1092
|
+
|
|
1093
|
+
choice = click.prompt(
|
|
1094
|
+
"\nYour choice(case insensitive)",
|
|
1095
|
+
type=click.Choice(
|
|
1096
|
+
["A", "C", "S"],
|
|
1097
|
+
case_sensitive=False,
|
|
1098
|
+
),
|
|
1099
|
+
default="S",
|
|
1100
|
+
)
|
|
1101
|
+
choice = choice.upper()
|
|
1102
|
+
|
|
1103
|
+
if choice == "A":
|
|
1104
|
+
echo_info("\nApproving deployment...")
|
|
1105
|
+
try:
|
|
1106
|
+
# Wait for deployment to reach approval stage
|
|
1107
|
+
asyncio.run(
|
|
1108
|
+
deployer.wait_for_approval_stage(deploy_id),
|
|
1109
|
+
)
|
|
1110
|
+
# Approve the deployment
|
|
1111
|
+
echo_info("Deployment approved by CLI.")
|
|
1112
|
+
asyncio.run(
|
|
1113
|
+
deployer.approve_deployment(
|
|
1114
|
+
deploy_id,
|
|
1115
|
+
wait=deploy_config.wait,
|
|
1116
|
+
timeout=deploy_config.timeout,
|
|
1117
|
+
),
|
|
1118
|
+
)
|
|
1119
|
+
echo_success("Deployment completed!")
|
|
1120
|
+
|
|
1121
|
+
# Get updated service info
|
|
1122
|
+
if deploy_config.wait:
|
|
1123
|
+
service = asyncio.run(
|
|
1124
|
+
deployer.get_service(service_name),
|
|
1125
|
+
)
|
|
1126
|
+
if service and service.internet_endpoint:
|
|
1127
|
+
echo_info(
|
|
1128
|
+
f"Service Endpoint: "
|
|
1129
|
+
f"{service.internet_endpoint}",
|
|
1130
|
+
)
|
|
1131
|
+
echo_info(
|
|
1132
|
+
f"\nDeployment is running. Use "
|
|
1133
|
+
f"'agentscope stop {deploy_id}' to stop it.",
|
|
1134
|
+
)
|
|
1135
|
+
except Exception as e:
|
|
1136
|
+
echo_error(f"Failed to approve deployment: {e}")
|
|
1137
|
+
sys.exit(1)
|
|
1138
|
+
|
|
1139
|
+
elif choice == "C":
|
|
1140
|
+
echo_info("\nCancelling deployment...")
|
|
1141
|
+
try:
|
|
1142
|
+
asyncio.run(
|
|
1143
|
+
deployer.wait_for_approval_stage(deploy_id),
|
|
1144
|
+
)
|
|
1145
|
+
asyncio.run(deployer.cancel_deployment(deploy_id))
|
|
1146
|
+
echo_warning("Deployment cancelled.")
|
|
1147
|
+
except Exception as e:
|
|
1148
|
+
echo_error(f"Failed to cancel deployment: {e}")
|
|
1149
|
+
sys.exit(1)
|
|
1150
|
+
|
|
1151
|
+
else: # choice == "S"
|
|
1152
|
+
echo_info(
|
|
1153
|
+
"\nSkipped. Please approve or cancel the deployment "
|
|
1154
|
+
"in the PAI console.",
|
|
1155
|
+
)
|
|
1156
|
+
else:
|
|
1157
|
+
# Non-interactive mode
|
|
1158
|
+
echo_warning(
|
|
1159
|
+
"\nNon-interactive mode: Please approve or cancel the "
|
|
1160
|
+
"deployment in the PAI console.",
|
|
1161
|
+
)
|
|
1162
|
+
|
|
1163
|
+
elif deploy_config.wait:
|
|
1164
|
+
echo_success("Deployment completed successfully!")
|
|
1165
|
+
echo_info(
|
|
1166
|
+
f"\nDeployment is running. Use 'agentscope stop "
|
|
1167
|
+
f"{deploy_id}' to stop it.",
|
|
1168
|
+
)
|
|
1169
|
+
|
|
1170
|
+
except Exception as e:
|
|
1171
|
+
echo_error(f"Deployment failed: {e}")
|
|
1172
|
+
import traceback
|
|
1173
|
+
|
|
1174
|
+
echo_error(traceback.format_exc())
|
|
1175
|
+
sys.exit(1)
|
|
1176
|
+
|
|
1177
|
+
|
|
714
1178
|
@deploy.command()
|
|
715
1179
|
@click.argument("source", required=True)
|
|
716
1180
|
@click.option("--name", help="Deployment name", default=None)
|
|
@@ -61,6 +61,22 @@ def _create_deployer(
|
|
|
61
61
|
)
|
|
62
62
|
|
|
63
63
|
return AgentRunDeployManager()
|
|
64
|
+
|
|
65
|
+
elif platform == "pai":
|
|
66
|
+
from agentscope_runtime.engine.deployers.pai_deployer import (
|
|
67
|
+
PAIDeployManager,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Extract workspace_id from deployment config
|
|
71
|
+
config = deployment_state.get("config", {})
|
|
72
|
+
workspace_id = config.get("workspace_id")
|
|
73
|
+
region = config.get("region_id")
|
|
74
|
+
oss_path = config.get("oss_path")
|
|
75
|
+
return PAIDeployManager(
|
|
76
|
+
workspace_id=workspace_id,
|
|
77
|
+
region_id=region,
|
|
78
|
+
oss_path=oss_path,
|
|
79
|
+
)
|
|
64
80
|
else:
|
|
65
81
|
echo_warning(f"Unknown platform: {platform}")
|
|
66
82
|
return None
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import sys
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from ..utils.lazy_loader import install_lazy_loader
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from .docker_client import DockerClient
|
|
9
|
+
from .kubernetes_client import KubernetesClient
|
|
10
|
+
from .knative_client import KnativeClient
|
|
11
|
+
from .fc_client import FCClient
|
|
12
|
+
from .agentrun_client import AgentRunClient
|
|
13
|
+
from .gvisor_client import GVisorDockerClient
|
|
14
|
+
from .boxlite_client import BoxliteClient
|
|
15
|
+
|
|
16
|
+
install_lazy_loader(
|
|
17
|
+
globals(),
|
|
18
|
+
{
|
|
19
|
+
"DockerClient": ".docker_client",
|
|
20
|
+
"KubernetesClient": ".kubernetes_client",
|
|
21
|
+
"KnativeClient": ".knative_client",
|
|
22
|
+
"FCClient": ".fc_client",
|
|
23
|
+
"AgentRunClient": ".agentrun_client",
|
|
24
|
+
"GVisorDockerClient": ".gvisor_client",
|
|
25
|
+
"BoxliteClient": ".boxlite_client",
|
|
26
|
+
},
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ContainerClientFactory:
|
|
31
|
+
_CLIENT_MAPPING = {
|
|
32
|
+
"docker": "DockerClient",
|
|
33
|
+
"k8s": "KubernetesClient",
|
|
34
|
+
"knative": "KnativeClient",
|
|
35
|
+
"fc": "FCClient",
|
|
36
|
+
"agentrun": "AgentRunClient",
|
|
37
|
+
"gvisor": "GVisorDockerClient",
|
|
38
|
+
"boxlite": "BoxliteClient",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@classmethod
|
|
42
|
+
def create_client(cls, deployment_type, config):
|
|
43
|
+
try:
|
|
44
|
+
class_name = cls._CLIENT_MAPPING[deployment_type]
|
|
45
|
+
except KeyError as e:
|
|
46
|
+
raise NotImplementedError(
|
|
47
|
+
f"Container deployment '{deployment_type}' not implemented",
|
|
48
|
+
) from e
|
|
49
|
+
|
|
50
|
+
module = sys.modules[__name__]
|
|
51
|
+
client_class = getattr(module, class_name)
|
|
52
|
+
return client_class(config=config)
|
|
@@ -1078,13 +1078,15 @@ class AgentRunClient(BaseClient):
|
|
|
1078
1078
|
"""
|
|
1079
1079
|
replacement_map = {
|
|
1080
1080
|
"agentscope/runtime-sandbox-base": "serverless-registry.cn-hangzhou.cr.aliyuncs.com/functionai" # noqa: E501
|
|
1081
|
-
"/agentscope_runtime-sandbox-base:
|
|
1081
|
+
"/agentscope_runtime-sandbox-base:20260106",
|
|
1082
1082
|
"agentscope/runtime-sandbox-browser": "serverless-registry.cn-hangzhou.cr.aliyuncs.com/functionai" # noqa: E501
|
|
1083
|
-
"/agentscope_runtime-sandbox-browser:
|
|
1083
|
+
"/agentscope_runtime-sandbox-browser:20260106",
|
|
1084
1084
|
"agentscope/runtime-sandbox-filesystem": "serverless-registry.cn-hangzhou.cr.aliyuncs.com/functionai" # noqa: E501
|
|
1085
|
-
"/agentscope_runtime-sandbox-filesystem:
|
|
1085
|
+
"/agentscope_runtime-sandbox-filesystem:20260106",
|
|
1086
1086
|
"agentscope/runtime-sandbox-gui": "serverless-registry.cn-hangzhou.cr.aliyuncs.com/functionai" # noqa: E501
|
|
1087
|
-
"/agentscope_runtime-sandbox-gui:
|
|
1087
|
+
"/agentscope_runtime-sandbox-gui:20260106",
|
|
1088
|
+
"agentscope/runtime-sandbox-mobile": "serverless-registry.cn-hangzhou.cr.aliyuncs.com/functionai" # noqa: E501
|
|
1089
|
+
"/agentscope_runtime-sandbox-mobile:20251217",
|
|
1088
1090
|
}
|
|
1089
1091
|
|
|
1090
1092
|
if ":" in image:
|