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.
Files changed (49) hide show
  1. agentscope_runtime/adapters/agentscope/stream.py +1 -1
  2. agentscope_runtime/adapters/langgraph/stream.py +120 -70
  3. agentscope_runtime/cli/commands/deploy.py +465 -1
  4. agentscope_runtime/cli/commands/stop.py +16 -0
  5. agentscope_runtime/common/container_clients/__init__.py +52 -0
  6. agentscope_runtime/common/container_clients/agentrun_client.py +6 -4
  7. agentscope_runtime/common/container_clients/boxlite_client.py +442 -0
  8. agentscope_runtime/common/container_clients/docker_client.py +0 -20
  9. agentscope_runtime/common/container_clients/fc_client.py +6 -4
  10. agentscope_runtime/common/container_clients/gvisor_client.py +38 -0
  11. agentscope_runtime/common/container_clients/knative_client.py +1 -0
  12. agentscope_runtime/common/utils/deprecation.py +164 -0
  13. agentscope_runtime/engine/app/agent_app.py +16 -4
  14. agentscope_runtime/engine/deployers/__init__.py +31 -20
  15. agentscope_runtime/engine/deployers/adapter/__init__.py +8 -0
  16. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +9 -8
  17. agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +19 -1
  18. agentscope_runtime/engine/deployers/adapter/agui/__init__.py +8 -0
  19. agentscope_runtime/engine/deployers/adapter/agui/agui_adapter_utils.py +652 -0
  20. agentscope_runtime/engine/deployers/adapter/agui/agui_protocol_adapter.py +225 -0
  21. agentscope_runtime/engine/deployers/pai_deployer.py +2335 -0
  22. agentscope_runtime/engine/deployers/utils/net_utils.py +37 -0
  23. agentscope_runtime/engine/deployers/utils/oss_utils.py +38 -0
  24. agentscope_runtime/engine/deployers/utils/package.py +46 -42
  25. agentscope_runtime/engine/helpers/agent_api_client.py +372 -0
  26. agentscope_runtime/engine/runner.py +1 -0
  27. agentscope_runtime/engine/schemas/agent_schemas.py +9 -3
  28. agentscope_runtime/engine/services/agent_state/__init__.py +7 -0
  29. agentscope_runtime/engine/services/memory/__init__.py +7 -0
  30. agentscope_runtime/engine/services/memory/redis_memory_service.py +15 -16
  31. agentscope_runtime/engine/services/session_history/__init__.py +7 -0
  32. agentscope_runtime/engine/tracing/local_logging_handler.py +2 -3
  33. agentscope_runtime/sandbox/box/sandbox.py +4 -0
  34. agentscope_runtime/sandbox/manager/sandbox_manager.py +11 -25
  35. agentscope_runtime/sandbox/manager/server/config.py +3 -1
  36. agentscope_runtime/sandbox/model/manager_config.py +11 -9
  37. agentscope_runtime/tools/modelstudio_memory/__init__.py +106 -0
  38. agentscope_runtime/tools/modelstudio_memory/base.py +220 -0
  39. agentscope_runtime/tools/modelstudio_memory/config.py +86 -0
  40. agentscope_runtime/tools/modelstudio_memory/core.py +594 -0
  41. agentscope_runtime/tools/modelstudio_memory/exceptions.py +60 -0
  42. agentscope_runtime/tools/modelstudio_memory/schemas.py +253 -0
  43. agentscope_runtime/version.py +1 -1
  44. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/METADATA +101 -62
  45. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/RECORD +49 -34
  46. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/WHEEL +0 -0
  47. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/entry_points.txt +0 -0
  48. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/licenses/LICENSE +0 -0
  49. {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(project_dir: str, entrypoint: str = None) -> str:
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:20251027",
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:20251027",
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:20251027",
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:20251027",
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: