veadk-python 0.2.27__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 (218) hide show
  1. veadk/__init__.py +37 -0
  2. veadk/a2a/__init__.py +13 -0
  3. veadk/a2a/agent_card.py +45 -0
  4. veadk/a2a/remote_ve_agent.py +390 -0
  5. veadk/a2a/utils/__init__.py +13 -0
  6. veadk/a2a/utils/agent_to_a2a.py +170 -0
  7. veadk/a2a/ve_a2a_server.py +93 -0
  8. veadk/a2a/ve_agent_executor.py +78 -0
  9. veadk/a2a/ve_middlewares.py +313 -0
  10. veadk/a2a/ve_task_store.py +37 -0
  11. veadk/agent.py +402 -0
  12. veadk/agent_builder.py +93 -0
  13. veadk/agents/loop_agent.py +68 -0
  14. veadk/agents/parallel_agent.py +72 -0
  15. veadk/agents/sequential_agent.py +64 -0
  16. veadk/auth/__init__.py +13 -0
  17. veadk/auth/base_auth.py +22 -0
  18. veadk/auth/ve_credential_service.py +203 -0
  19. veadk/auth/veauth/__init__.py +13 -0
  20. veadk/auth/veauth/apmplus_veauth.py +58 -0
  21. veadk/auth/veauth/ark_veauth.py +75 -0
  22. veadk/auth/veauth/base_veauth.py +50 -0
  23. veadk/auth/veauth/cozeloop_veauth.py +13 -0
  24. veadk/auth/veauth/opensearch_veauth.py +75 -0
  25. veadk/auth/veauth/postgresql_veauth.py +75 -0
  26. veadk/auth/veauth/prompt_pilot_veauth.py +60 -0
  27. veadk/auth/veauth/speech_veauth.py +54 -0
  28. veadk/auth/veauth/utils.py +69 -0
  29. veadk/auth/veauth/vesearch_veauth.py +62 -0
  30. veadk/auth/veauth/viking_mem0_veauth.py +91 -0
  31. veadk/cli/__init__.py +13 -0
  32. veadk/cli/cli.py +58 -0
  33. veadk/cli/cli_clean.py +87 -0
  34. veadk/cli/cli_create.py +163 -0
  35. veadk/cli/cli_deploy.py +233 -0
  36. veadk/cli/cli_eval.py +215 -0
  37. veadk/cli/cli_init.py +214 -0
  38. veadk/cli/cli_kb.py +110 -0
  39. veadk/cli/cli_pipeline.py +285 -0
  40. veadk/cli/cli_prompt.py +86 -0
  41. veadk/cli/cli_update.py +106 -0
  42. veadk/cli/cli_uploadevalset.py +139 -0
  43. veadk/cli/cli_web.py +143 -0
  44. veadk/cloud/__init__.py +13 -0
  45. veadk/cloud/cloud_agent_engine.py +485 -0
  46. veadk/cloud/cloud_app.py +475 -0
  47. veadk/config.py +115 -0
  48. veadk/configs/__init__.py +13 -0
  49. veadk/configs/auth_configs.py +133 -0
  50. veadk/configs/database_configs.py +132 -0
  51. veadk/configs/model_configs.py +78 -0
  52. veadk/configs/tool_configs.py +54 -0
  53. veadk/configs/tracing_configs.py +110 -0
  54. veadk/consts.py +74 -0
  55. veadk/evaluation/__init__.py +17 -0
  56. veadk/evaluation/adk_evaluator/__init__.py +17 -0
  57. veadk/evaluation/adk_evaluator/adk_evaluator.py +302 -0
  58. veadk/evaluation/base_evaluator.py +642 -0
  59. veadk/evaluation/deepeval_evaluator/__init__.py +17 -0
  60. veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +339 -0
  61. veadk/evaluation/eval_set_file_loader.py +48 -0
  62. veadk/evaluation/eval_set_recorder.py +146 -0
  63. veadk/evaluation/types.py +65 -0
  64. veadk/evaluation/utils/prometheus.py +196 -0
  65. veadk/integrations/__init__.py +13 -0
  66. veadk/integrations/ve_apig/__init__.py +13 -0
  67. veadk/integrations/ve_apig/ve_apig.py +349 -0
  68. veadk/integrations/ve_apig/ve_apig_utils.py +332 -0
  69. veadk/integrations/ve_code_pipeline/__init__.py +13 -0
  70. veadk/integrations/ve_code_pipeline/ve_code_pipeline.py +431 -0
  71. veadk/integrations/ve_cozeloop/__init__.py +13 -0
  72. veadk/integrations/ve_cozeloop/ve_cozeloop.py +96 -0
  73. veadk/integrations/ve_cr/__init__.py +13 -0
  74. veadk/integrations/ve_cr/ve_cr.py +220 -0
  75. veadk/integrations/ve_faas/__init__.py +13 -0
  76. veadk/integrations/ve_faas/template/cookiecutter.json +15 -0
  77. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
  78. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
  79. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/config.yaml.example +6 -0
  80. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/deploy.py +106 -0
  81. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/__init__.py +13 -0
  82. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/agent.py +25 -0
  83. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +202 -0
  84. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +3 -0
  85. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +49 -0
  86. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/__init__.py +14 -0
  87. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/agent.py +27 -0
  88. veadk/integrations/ve_faas/ve_faas.py +754 -0
  89. veadk/integrations/ve_faas/ve_faas_utils.py +408 -0
  90. veadk/integrations/ve_faas/web_template/cookiecutter.json +20 -0
  91. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
  92. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
  93. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/config.yaml.example +2 -0
  94. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/deploy.py +44 -0
  95. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/Dockerfile +23 -0
  96. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/app.py +123 -0
  97. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/init_db.py +46 -0
  98. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/models.py +36 -0
  99. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/requirements.txt +4 -0
  100. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/run.sh +21 -0
  101. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/css/style.css +368 -0
  102. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/js/admin.js +0 -0
  103. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/dashboard.html +21 -0
  104. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/edit_post.html +24 -0
  105. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/login.html +21 -0
  106. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/posts.html +53 -0
  107. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/base.html +45 -0
  108. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/index.html +29 -0
  109. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/post.html +14 -0
  110. veadk/integrations/ve_identity/__init__.py +110 -0
  111. veadk/integrations/ve_identity/auth_config.py +261 -0
  112. veadk/integrations/ve_identity/auth_mixins.py +650 -0
  113. veadk/integrations/ve_identity/auth_processor.py +385 -0
  114. veadk/integrations/ve_identity/function_tool.py +158 -0
  115. veadk/integrations/ve_identity/identity_client.py +864 -0
  116. veadk/integrations/ve_identity/mcp_tool.py +181 -0
  117. veadk/integrations/ve_identity/mcp_toolset.py +431 -0
  118. veadk/integrations/ve_identity/models.py +228 -0
  119. veadk/integrations/ve_identity/token_manager.py +188 -0
  120. veadk/integrations/ve_identity/utils.py +151 -0
  121. veadk/integrations/ve_prompt_pilot/__init__.py +13 -0
  122. veadk/integrations/ve_prompt_pilot/ve_prompt_pilot.py +85 -0
  123. veadk/integrations/ve_tls/__init__.py +13 -0
  124. veadk/integrations/ve_tls/utils.py +116 -0
  125. veadk/integrations/ve_tls/ve_tls.py +212 -0
  126. veadk/integrations/ve_tos/ve_tos.py +710 -0
  127. veadk/integrations/ve_viking_db_memory/__init__.py +13 -0
  128. veadk/integrations/ve_viking_db_memory/ve_viking_db_memory.py +308 -0
  129. veadk/knowledgebase/__init__.py +17 -0
  130. veadk/knowledgebase/backends/__init__.py +13 -0
  131. veadk/knowledgebase/backends/base_backend.py +72 -0
  132. veadk/knowledgebase/backends/in_memory_backend.py +91 -0
  133. veadk/knowledgebase/backends/opensearch_backend.py +162 -0
  134. veadk/knowledgebase/backends/redis_backend.py +172 -0
  135. veadk/knowledgebase/backends/utils.py +92 -0
  136. veadk/knowledgebase/backends/vikingdb_knowledge_backend.py +608 -0
  137. veadk/knowledgebase/entry.py +25 -0
  138. veadk/knowledgebase/knowledgebase.py +307 -0
  139. veadk/memory/__init__.py +35 -0
  140. veadk/memory/long_term_memory.py +365 -0
  141. veadk/memory/long_term_memory_backends/__init__.py +13 -0
  142. veadk/memory/long_term_memory_backends/base_backend.py +35 -0
  143. veadk/memory/long_term_memory_backends/in_memory_backend.py +67 -0
  144. veadk/memory/long_term_memory_backends/mem0_backend.py +155 -0
  145. veadk/memory/long_term_memory_backends/opensearch_backend.py +124 -0
  146. veadk/memory/long_term_memory_backends/redis_backend.py +140 -0
  147. veadk/memory/long_term_memory_backends/vikingdb_memory_backend.py +189 -0
  148. veadk/memory/short_term_memory.py +252 -0
  149. veadk/memory/short_term_memory_backends/__init__.py +13 -0
  150. veadk/memory/short_term_memory_backends/base_backend.py +31 -0
  151. veadk/memory/short_term_memory_backends/mysql_backend.py +49 -0
  152. veadk/memory/short_term_memory_backends/postgresql_backend.py +49 -0
  153. veadk/memory/short_term_memory_backends/sqlite_backend.py +55 -0
  154. veadk/memory/short_term_memory_processor.py +100 -0
  155. veadk/processors/__init__.py +26 -0
  156. veadk/processors/base_run_processor.py +120 -0
  157. veadk/prompts/__init__.py +13 -0
  158. veadk/prompts/agent_default_prompt.py +30 -0
  159. veadk/prompts/prompt_evaluator.py +20 -0
  160. veadk/prompts/prompt_memory_processor.py +55 -0
  161. veadk/prompts/prompt_optimization.py +150 -0
  162. veadk/runner.py +732 -0
  163. veadk/tools/__init__.py +13 -0
  164. veadk/tools/builtin_tools/__init__.py +13 -0
  165. veadk/tools/builtin_tools/agent_authorization.py +94 -0
  166. veadk/tools/builtin_tools/generate_image.py +23 -0
  167. veadk/tools/builtin_tools/image_edit.py +300 -0
  168. veadk/tools/builtin_tools/image_generate.py +446 -0
  169. veadk/tools/builtin_tools/lark.py +67 -0
  170. veadk/tools/builtin_tools/las.py +24 -0
  171. veadk/tools/builtin_tools/link_reader.py +66 -0
  172. veadk/tools/builtin_tools/llm_shield.py +381 -0
  173. veadk/tools/builtin_tools/load_knowledgebase.py +97 -0
  174. veadk/tools/builtin_tools/mcp_router.py +29 -0
  175. veadk/tools/builtin_tools/run_code.py +113 -0
  176. veadk/tools/builtin_tools/tts.py +253 -0
  177. veadk/tools/builtin_tools/vesearch.py +49 -0
  178. veadk/tools/builtin_tools/video_generate.py +363 -0
  179. veadk/tools/builtin_tools/web_scraper.py +76 -0
  180. veadk/tools/builtin_tools/web_search.py +83 -0
  181. veadk/tools/demo_tools.py +58 -0
  182. veadk/tools/load_knowledgebase_tool.py +149 -0
  183. veadk/tools/sandbox/__init__.py +13 -0
  184. veadk/tools/sandbox/browser_sandbox.py +37 -0
  185. veadk/tools/sandbox/code_sandbox.py +40 -0
  186. veadk/tools/sandbox/computer_sandbox.py +34 -0
  187. veadk/tracing/__init__.py +13 -0
  188. veadk/tracing/base_tracer.py +58 -0
  189. veadk/tracing/telemetry/__init__.py +13 -0
  190. veadk/tracing/telemetry/attributes/attributes.py +29 -0
  191. veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +180 -0
  192. veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +858 -0
  193. veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py +152 -0
  194. veadk/tracing/telemetry/attributes/extractors/types.py +164 -0
  195. veadk/tracing/telemetry/exporters/__init__.py +13 -0
  196. veadk/tracing/telemetry/exporters/apmplus_exporter.py +558 -0
  197. veadk/tracing/telemetry/exporters/base_exporter.py +39 -0
  198. veadk/tracing/telemetry/exporters/cozeloop_exporter.py +129 -0
  199. veadk/tracing/telemetry/exporters/inmemory_exporter.py +248 -0
  200. veadk/tracing/telemetry/exporters/tls_exporter.py +139 -0
  201. veadk/tracing/telemetry/opentelemetry_tracer.py +320 -0
  202. veadk/tracing/telemetry/telemetry.py +411 -0
  203. veadk/types.py +47 -0
  204. veadk/utils/__init__.py +13 -0
  205. veadk/utils/audio_manager.py +95 -0
  206. veadk/utils/auth.py +294 -0
  207. veadk/utils/logger.py +59 -0
  208. veadk/utils/mcp_utils.py +44 -0
  209. veadk/utils/misc.py +184 -0
  210. veadk/utils/patches.py +101 -0
  211. veadk/utils/volcengine_sign.py +205 -0
  212. veadk/version.py +15 -0
  213. veadk_python-0.2.27.dist-info/METADATA +373 -0
  214. veadk_python-0.2.27.dist-info/RECORD +218 -0
  215. veadk_python-0.2.27.dist-info/WHEEL +5 -0
  216. veadk_python-0.2.27.dist-info/entry_points.txt +2 -0
  217. veadk_python-0.2.27.dist-info/licenses/LICENSE +201 -0
  218. veadk_python-0.2.27.dist-info/top_level.txt +1 -0
@@ -0,0 +1,485 @@
1
+ # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import json
16
+ import os
17
+ import socket
18
+ import subprocess
19
+ import time
20
+ from pathlib import Path
21
+ from typing import Any
22
+
23
+ from pydantic import BaseModel
24
+
25
+ from veadk.cloud.cloud_app import CloudApp
26
+ from veadk.config import getenv, veadk_environments
27
+ from veadk.integrations.ve_apig.ve_apig import APIGateway
28
+ from veadk.integrations.ve_faas.ve_faas import VeFaaS
29
+ from veadk.integrations.ve_identity.identity_client import IdentityClient
30
+ from veadk.utils.logger import get_logger
31
+ from veadk.utils.misc import formatted_timestamp
32
+
33
+ logger = get_logger(__name__)
34
+
35
+
36
+ class CloudAgentEngine(BaseModel):
37
+ """Manages cloud agent deployment and operations on Volcengine FaaS platform.
38
+
39
+ This class handles authentication with Volcengine, deploys local projects to FaaS,
40
+ updates function code, removes applications, and supports local testing.
41
+
42
+ Attributes:
43
+ volcengine_access_key (str): Access key for Volcengine authentication.
44
+ Defaults to VOLCENGINE_ACCESS_KEY environment variable.
45
+ volcengine_secret_key (str): Secret key for Volcengine authentication.
46
+ Defaults to VOLCENGINE_SECRET_KEY environment variable.
47
+ region (str): Region for Volcengine services. Defaults to "cn-beijing".
48
+ _vefaas_service (VeFaaS): Internal VeFaaS client instance, initialized post-creation.
49
+ _veapig_service (APIGateway): Internal VeAPIG client instance, initialized post-creation.
50
+ _veidentity_service (IdentityClient): Internal Identity client instance, initialized post-creation.
51
+
52
+ Note:
53
+ Credentials must be set via environment variables for default behavior.
54
+ This class performs interactive confirmations for destructive operations like removal.
55
+
56
+ Examples:
57
+ ```python
58
+ from veadk.cloud.cloud_agent_engine import CloudAgentEngine
59
+ engine = CloudAgentEngine()
60
+ app = engine.deploy("test-app", "/path/to/local/project")
61
+ print(app.vefaas_endpoint)
62
+ ```
63
+ """
64
+
65
+ volcengine_access_key: str = getenv(
66
+ "VOLCENGINE_ACCESS_KEY", "", allow_false_values=True
67
+ )
68
+ volcengine_secret_key: str = getenv(
69
+ "VOLCENGINE_SECRET_KEY", "", allow_false_values=True
70
+ )
71
+ region: str = "cn-beijing"
72
+
73
+ def model_post_init(self, context: Any, /) -> None:
74
+ """Initializes the internal VeFaaS service after Pydantic model validation.
75
+
76
+ Creates a VeFaaS instance using the configured access key, secret key, and region.
77
+
78
+ Args:
79
+ self: The CloudAgentEngine instance.
80
+ context: Pydantic post-init context parameter (not used).
81
+
82
+ Returns:
83
+ None
84
+
85
+ Note:
86
+ This is a Pydantic lifecycle method, ensuring service readiness after init.
87
+ """
88
+ self._vefaas_service = VeFaaS(
89
+ access_key=self.volcengine_access_key,
90
+ secret_key=self.volcengine_secret_key,
91
+ region=self.region,
92
+ )
93
+ self._veapig_service = APIGateway(
94
+ access_key=self.volcengine_access_key,
95
+ secret_key=self.volcengine_secret_key,
96
+ region=self.region,
97
+ )
98
+ self._veidentity_service = IdentityClient(
99
+ access_key=self.volcengine_access_key,
100
+ secret_key=self.volcengine_secret_key,
101
+ region=self.region,
102
+ )
103
+
104
+ def _prepare(self, path: str, name: str):
105
+ """Prepares the local project for deployment by validating path and name.
106
+
107
+ Checks if the path exists and is a directory, validates application name format.
108
+
109
+ Args:
110
+ path (str): Full or relative path to the local agent project directory.
111
+ name (str): Intended VeFaaS application name.
112
+
113
+ Returns:
114
+ None
115
+
116
+ Raises:
117
+ AssertionError: If path does not exist or is not a directory.
118
+ ValueError: If name contains invalid characters like underscores.
119
+
120
+ Note:
121
+ Includes commented code for handling requirements.txt; not executed currently.
122
+ Called internally by deploy and update methods.
123
+ """
124
+ # basic check
125
+ assert os.path.exists(path), f"Local agent project path `{path}` not exists."
126
+ assert os.path.isdir(path), (
127
+ f"Local agent project path `{path}` is not a directory."
128
+ )
129
+
130
+ # VeFaaS application/function name check
131
+ if "_" in name:
132
+ raise ValueError(
133
+ f"Invalid Volcengine FaaS function name `{name}`, please use lowercase letters and numbers, or replace it with a `-` char."
134
+ )
135
+
136
+ # # copy user's requirements.txt
137
+ # module = load_module_from_file(
138
+ # module_name="agent_source", file_path=f"{path}/agent.py"
139
+ # )
140
+
141
+ # requirement_file_path = module.agent_run_config.requirement_file_path
142
+ # if Path(requirement_file_path).exists():
143
+ # shutil.copy(requirement_file_path, os.path.join(path, "requirements.txt"))
144
+
145
+ # logger.info(
146
+ # f"Copy requirement file: from {requirement_file_path} to {path}/requirements.txt"
147
+ # )
148
+ # else:
149
+ # logger.warning(
150
+ # f"Requirement file: {requirement_file_path} not found or you have no requirement file in your project. Use a default one."
151
+ # )
152
+
153
+ def _try_launch_fastapi_server(self, path: str):
154
+ """Tries to start a FastAPI server locally for testing deployment readiness.
155
+
156
+ Runs the project's run.sh script and checks connectivity on port 8000.
157
+
158
+ Args:
159
+ path (str): Path to the local project containing run.sh.
160
+
161
+ Returns:
162
+ None
163
+
164
+ Raises:
165
+ RuntimeError: If server startup times out after 30 seconds.
166
+
167
+ Note:
168
+ Sets _FAAS_FUNC_TIMEOUT environment to 900 seconds.
169
+ Streams output to console and terminates process after successful check.
170
+ Assumes run.sh launches server on 0.0.0.0:8000.
171
+ """
172
+ RUN_SH = f"{path}/run.sh"
173
+
174
+ HOST = "0.0.0.0"
175
+ PORT = 8000
176
+
177
+ # Prepare environment variables
178
+ os.environ["_FAAS_FUNC_TIMEOUT"] = "900"
179
+ env = os.environ.copy()
180
+
181
+ process = subprocess.Popen(
182
+ ["bash", RUN_SH],
183
+ stdout=subprocess.PIPE,
184
+ stderr=subprocess.STDOUT,
185
+ text=True,
186
+ env=env,
187
+ bufsize=1,
188
+ )
189
+
190
+ timeout = 30
191
+ start_time = time.time()
192
+
193
+ for line in process.stdout: # type: ignore
194
+ print(line, end="")
195
+
196
+ if time.time() - start_time > timeout:
197
+ process.terminate()
198
+ raise RuntimeError(f"FastAPI server failed to start on {HOST}:{PORT}")
199
+ try:
200
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
201
+ s.settimeout(0.1)
202
+ s.connect(("127.0.0.1", PORT))
203
+ logger.info(f"FastAPI server is listening on {HOST}:{PORT}")
204
+ logger.info("Local deplyment test successfully.")
205
+ break
206
+ except (ConnectionRefusedError, socket.timeout):
207
+ continue
208
+
209
+ process.terminate()
210
+ process.wait()
211
+
212
+ def deploy(
213
+ self,
214
+ application_name: str,
215
+ path: str,
216
+ gateway_name: str = "",
217
+ gateway_service_name: str = "",
218
+ gateway_upstream_name: str = "",
219
+ use_adk_web: bool = False,
220
+ auth_method: str = "none",
221
+ identity_user_pool_name: str = "",
222
+ identity_client_name: str = "",
223
+ local_test: bool = False,
224
+ ) -> CloudApp:
225
+ """Deploys a local agent project to Volcengine FaaS, creating necessary resources.
226
+
227
+ Prepares project, optionally tests locally, deploys via VeFaaS, and returns app instance.
228
+
229
+ Args:
230
+ application_name (str): Unique name for the VeFaaS application.
231
+ path (str): Local directory path of the agent project.
232
+ gateway_name (str, optional): Custom gateway resource name. Defaults to timestamped.
233
+ gateway_service_name (str, optional): Custom service name. Defaults to timestamped.
234
+ gateway_upstream_name (str, optional): Custom upstream name. Defaults to timestamped.
235
+ use_adk_web (bool): Enable ADK Web configuration. Defaults to False.
236
+ auth_method (str, optional): Authentication for the agent. Defaults to none.
237
+ identity_user_pool_name (str, optional): Custom user pool name. Defaults to timestamped.
238
+ identity_client_name (str, optional): Custom client name. Defaults to timestamped.
239
+ local_test (bool): Perform FastAPI server test before deploy. Defaults to False.
240
+
241
+ Returns:
242
+ CloudApp: Deployed application with endpoint, name, and ID.
243
+
244
+ Raises:
245
+ ValueError: On deployment failure, such as invalid config or VeFaaS errors.
246
+
247
+ Note:
248
+ Converts path to absolute; sets telemetry opt-out and ADK Web env vars.
249
+ Generates default gateway names if not specified.
250
+
251
+ Examples:
252
+ ```python
253
+ app = engine.deploy("my-agent", "./agent-project", local_test=True)
254
+ print(f"Deployed at: {app.vefaas_endpoint}")
255
+ ```
256
+ """
257
+ # prevent deepeval writing operations
258
+ veadk_environments["DEEPEVAL_TELEMETRY_OPT_OUT"] = "YES"
259
+
260
+ enable_key_auth = False
261
+ if auth_method == "api-key":
262
+ enable_key_auth = True
263
+
264
+ if use_adk_web:
265
+ veadk_environments["USE_ADK_WEB"] = "True"
266
+ else:
267
+ veadk_environments["USE_ADK_WEB"] = "False"
268
+
269
+ # convert `path` to absolute path
270
+ path = str(Path(path).resolve())
271
+ self._prepare(path, application_name)
272
+
273
+ if local_test:
274
+ self._try_launch_fastapi_server(path)
275
+
276
+ if not gateway_name:
277
+ gateway_name = f"{application_name}-gw-{formatted_timestamp()}"
278
+ if not gateway_service_name:
279
+ gateway_service_name = f"{application_name}-gw-svr-{formatted_timestamp()}"
280
+ if not gateway_upstream_name:
281
+ gateway_upstream_name = f"{application_name}-gw-us-{formatted_timestamp()}"
282
+ if not identity_user_pool_name:
283
+ identity_user_pool_name = (
284
+ f"{application_name}-id-up-{formatted_timestamp()}"
285
+ )
286
+ if not identity_client_name:
287
+ identity_client_name = f"{application_name}-id-cli-{formatted_timestamp()}"
288
+
289
+ try:
290
+ vefaas_application_url, app_id, function_id = self._vefaas_service.deploy(
291
+ path=path,
292
+ name=application_name,
293
+ gateway_name=gateway_name,
294
+ gateway_service_name=gateway_service_name,
295
+ gateway_upstream_name=gateway_upstream_name,
296
+ enable_key_auth=enable_key_auth,
297
+ )
298
+ _ = function_id # for future use
299
+
300
+ veapig_gateway_id, _, veapig_route_id = (
301
+ self._vefaas_service.get_application_route(app_id=app_id)
302
+ )
303
+
304
+ if auth_method == "oauth2":
305
+ # Get or create the Identity user pool.
306
+ identity_user_pool_id = self._veidentity_service.get_user_pool(
307
+ name=identity_user_pool_name,
308
+ )
309
+ if not identity_user_pool_id:
310
+ identity_user_pool_id = self._veidentity_service.create_user_pool(
311
+ name=identity_user_pool_name,
312
+ )
313
+ issuer = f"https://auth.id.{self.region}.volces.com/userpool/{identity_user_pool_id}"
314
+
315
+ # Create APIG upstream for Identity.
316
+ identity_domain = f"auth.id.{self.region}.volces.com"
317
+ veapig_identity_upstream_id = (
318
+ self._veapig_service.check_domain_upstream_exist(
319
+ domain=identity_domain,
320
+ port=443,
321
+ gateway_id=veapig_gateway_id,
322
+ )
323
+ )
324
+ if not veapig_identity_upstream_id:
325
+ veapig_identity_upstream_id = (
326
+ self._veapig_service.create_domain_upstream(
327
+ domain=f"auth.id.{self.region}.volces.com",
328
+ port=443,
329
+ is_https=True,
330
+ gateway_id=veapig_gateway_id,
331
+ upstream_name=f"id-{formatted_timestamp()}",
332
+ )
333
+ )
334
+
335
+ # Create plugin binding.
336
+ plugin_name = ""
337
+ plugin_config = {}
338
+ if use_adk_web:
339
+ # Get or create the Identity client.
340
+ identity_client_id = ""
341
+ identity_client_secret = ""
342
+ identity_client = self._veidentity_service.get_user_pool_client(
343
+ user_pool_uid=identity_user_pool_id,
344
+ name=identity_client_name,
345
+ )
346
+ if identity_client:
347
+ identity_client_id = identity_client[0]
348
+ identity_client_secret = identity_client[1]
349
+ else:
350
+ identity_client_id, identity_client_secret = (
351
+ self._veidentity_service.create_user_pool_client(
352
+ user_pool_uid=identity_user_pool_id,
353
+ name=identity_client_name,
354
+ client_type="WEB_APPLICATION",
355
+ )
356
+ )
357
+
358
+ self._veidentity_service.register_callback_for_user_pool_client(
359
+ user_pool_uid=identity_user_pool_id,
360
+ client_uid=identity_client_id,
361
+ callback_url=f"{vefaas_application_url}/callback",
362
+ web_origin=vefaas_application_url,
363
+ )
364
+
365
+ plugin_name = "wasm-oauth2-sso"
366
+ plugin_config = {
367
+ "AuthorizationUrl": f"{issuer}/authorize",
368
+ "UpstreamId": veapig_identity_upstream_id,
369
+ "TokenUrl": f"{issuer}/oauth/token",
370
+ "RedirectPath": "/callback",
371
+ "SignoutPath": "/signout",
372
+ "ClientId": identity_client_id,
373
+ "ClientSecret": identity_client_secret,
374
+ }
375
+ else:
376
+ plugin_name = "wasm-jwt-auth"
377
+ plugin_config = {
378
+ "RemoteJwks": {
379
+ "UpstreamId": veapig_identity_upstream_id,
380
+ "Url": f"{issuer}/keys",
381
+ },
382
+ "Issuer": issuer,
383
+ "ValidateConsumer": False,
384
+ }
385
+ self._vefaas_service.apig_client.create_plugin_binding(
386
+ scope="ROUTE",
387
+ target=veapig_route_id,
388
+ plugin_name=plugin_name,
389
+ plugin_config=json.dumps(plugin_config),
390
+ )
391
+
392
+ return CloudApp(
393
+ vefaas_application_name=application_name,
394
+ vefaas_endpoint=vefaas_application_url,
395
+ vefaas_application_id=app_id,
396
+ )
397
+ except Exception as e:
398
+ raise ValueError(
399
+ f"Failed to deploy local agent project to Volcengine FaaS platform. Error: {e}"
400
+ )
401
+
402
+ def remove(self, app_name: str):
403
+ """Deletes a deployed cloud application after user confirmation.
404
+
405
+ Locates app by name, confirms, and issues delete via VeFaaS.
406
+
407
+ Args:
408
+ app_name (str): Name of the application to remove.
409
+
410
+ Returns:
411
+ None
412
+
413
+ Raises:
414
+ ValueError: If application not found by name.
415
+
416
+ Note:
417
+ Interactive prompt required; cancels on non-'y' input.
418
+ Deletion is processed asynchronously by VeFaaS.
419
+
420
+ Examples:
421
+ ```python
422
+ engine.remove("my-agent")
423
+ ```
424
+ """
425
+ confirm = input(f"Confirm delete cloud app {app_name}? (y/N): ")
426
+ if confirm.lower() != "y":
427
+ print("Delete cancelled.")
428
+ return
429
+ else:
430
+ app_id = self._vefaas_service.find_app_id_by_name(app_name)
431
+ if not app_id:
432
+ raise ValueError(
433
+ f"Cloud app {app_name} not found, cannot delete it. Please check the app name."
434
+ )
435
+ self._vefaas_service.delete(app_id)
436
+
437
+ def update_function_code(
438
+ self,
439
+ application_name: str,
440
+ path: str,
441
+ ) -> CloudApp:
442
+ """Updates the code in an existing VeFaaS application without changing endpoint.
443
+
444
+ Prepares new code from local path and updates function via VeFaaS.
445
+
446
+ Args:
447
+ application_name (str): Name of the existing application to update.
448
+ path (str): Local path containing updated project files.
449
+
450
+ Returns:
451
+ CloudApp: Updated application instance with same endpoint.
452
+
453
+ Raises:
454
+ ValueError: If update fails due to preparation or VeFaaS issues.
455
+
456
+ Note:
457
+ Preserves gateway and other resources; only function code is updated.
458
+ Path is resolved to absolute before processing.
459
+
460
+ Examples:
461
+ ```python
462
+ updated_app = engine.update_function_code("my-agent", "./updated-project")
463
+ ```
464
+ """
465
+ # convert `path` to absolute path
466
+ path = str(Path(path).resolve())
467
+ self._prepare(path, application_name)
468
+
469
+ try:
470
+ vefaas_application_url, app_id, function_id = (
471
+ self._vefaas_service._update_function_code(
472
+ application_name=application_name,
473
+ path=path,
474
+ )
475
+ )
476
+
477
+ return CloudApp(
478
+ vefaas_application_name=application_name,
479
+ vefaas_endpoint=vefaas_application_url,
480
+ vefaas_application_id=app_id,
481
+ )
482
+ except Exception as e:
483
+ raise ValueError(
484
+ f"Failed to update agent project on Volcengine FaaS platform. Error: {e}"
485
+ )