agentkit-sdk-python 0.1.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 (120) hide show
  1. agentkit/__init__.py +23 -0
  2. agentkit/apps/__init__.py +58 -0
  3. agentkit/apps/a2a_app/__init__.py +13 -0
  4. agentkit/apps/a2a_app/a2a_app.py +134 -0
  5. agentkit/apps/a2a_app/telemetry.py +119 -0
  6. agentkit/apps/agent_server_app/__init__.py +13 -0
  7. agentkit/apps/agent_server_app/agent_server_app.py +85 -0
  8. agentkit/apps/base_app.py +20 -0
  9. agentkit/apps/mcp_app/__init__.py +13 -0
  10. agentkit/apps/mcp_app/mcp_app.py +150 -0
  11. agentkit/apps/mcp_app/telemetry.py +115 -0
  12. agentkit/apps/simple_app/__init__.py +13 -0
  13. agentkit/apps/simple_app/simple_app.py +94 -0
  14. agentkit/apps/simple_app/simple_app_handlers.py +325 -0
  15. agentkit/apps/simple_app/telemetry.py +124 -0
  16. agentkit/apps/utils.py +45 -0
  17. agentkit/client/__init__.py +26 -0
  18. agentkit/client/base_client.py +219 -0
  19. agentkit/identity/__init__.py +13 -0
  20. agentkit/identity/auth.py +70 -0
  21. agentkit/knowledge/__init__.py +47 -0
  22. agentkit/knowledge/knowledge.py +203 -0
  23. agentkit/knowledge/knowledge_all_types.py +191 -0
  24. agentkit/mcp/__init__.py +79 -0
  25. agentkit/mcp/mcp.py +294 -0
  26. agentkit/mcp/mcp_all_types.py +1212 -0
  27. agentkit/memory/__init__.py +71 -0
  28. agentkit/memory/memory.py +236 -0
  29. agentkit/memory/memory_all_types.py +358 -0
  30. agentkit/runtime/__init__.py +13 -0
  31. agentkit/runtime/runtime.py +191 -0
  32. agentkit/runtime/runtime_all_types.py +624 -0
  33. agentkit/runtime/runtime_v1.py +178 -0
  34. agentkit/runtime/types.py +188 -0
  35. agentkit/toolkit/__init__.py +13 -0
  36. agentkit/toolkit/cli/__init__.py +13 -0
  37. agentkit/toolkit/cli/__main__.py +7 -0
  38. agentkit/toolkit/cli/cli.py +97 -0
  39. agentkit/toolkit/cli/cli_build.py +53 -0
  40. agentkit/toolkit/cli/cli_config.py +170 -0
  41. agentkit/toolkit/cli/cli_deploy.py +52 -0
  42. agentkit/toolkit/cli/cli_destroy.py +53 -0
  43. agentkit/toolkit/cli/cli_init.py +364 -0
  44. agentkit/toolkit/cli/cli_invoke.py +168 -0
  45. agentkit/toolkit/cli/cli_launch.py +34 -0
  46. agentkit/toolkit/cli/cli_status.py +53 -0
  47. agentkit/toolkit/cli/cli_version.py +87 -0
  48. agentkit/toolkit/cli/utils.py +47 -0
  49. agentkit/toolkit/config/__init__.py +52 -0
  50. agentkit/toolkit/config/auto_prompt.py +752 -0
  51. agentkit/toolkit/config/build_config.py +28 -0
  52. agentkit/toolkit/config/common_config.py +18 -0
  53. agentkit/toolkit/config/config.py +306 -0
  54. agentkit/toolkit/config/config_handler.py +331 -0
  55. agentkit/toolkit/config/config_manager.py +48 -0
  56. agentkit/toolkit/config/config_validator.py +121 -0
  57. agentkit/toolkit/config/constants.py +18 -0
  58. agentkit/toolkit/config/dataclass_utils.py +153 -0
  59. agentkit/toolkit/config/deploy_config.py +1 -0
  60. agentkit/toolkit/config/utils.py +57 -0
  61. agentkit/toolkit/config/workflow_configs.py +149 -0
  62. agentkit/toolkit/consts.py +1 -0
  63. agentkit/toolkit/core/__init__.py +13 -0
  64. agentkit/toolkit/core/build/__init__.py +13 -0
  65. agentkit/toolkit/core/build/base_builder.py +6 -0
  66. agentkit/toolkit/core/build/cloud_builder.py +0 -0
  67. agentkit/toolkit/core/build/local_builder.py +0 -0
  68. agentkit/toolkit/core/deploy/__init__.py +13 -0
  69. agentkit/toolkit/core/deploy/base_deployer.py +6 -0
  70. agentkit/toolkit/core/deploy/cloud_deployer.py +0 -0
  71. agentkit/toolkit/core/deploy/local_deployer.py +0 -0
  72. agentkit/toolkit/integrations/__init__.py +17 -0
  73. agentkit/toolkit/integrations/builder/__init__.py +23 -0
  74. agentkit/toolkit/integrations/builder/base.py +59 -0
  75. agentkit/toolkit/integrations/builder/local_docker_builder.py +163 -0
  76. agentkit/toolkit/integrations/builder/ve_core_pipeline_builder.py +853 -0
  77. agentkit/toolkit/integrations/container.py +843 -0
  78. agentkit/toolkit/integrations/runner/__init__.py +26 -0
  79. agentkit/toolkit/integrations/runner/base.py +222 -0
  80. agentkit/toolkit/integrations/runner/local_docker_runner.py +407 -0
  81. agentkit/toolkit/integrations/runner/ve_agentkit_runner.py +665 -0
  82. agentkit/toolkit/integrations/services/__init__.py +26 -0
  83. agentkit/toolkit/integrations/services/cr_service.py +449 -0
  84. agentkit/toolkit/integrations/services/tos_service.py +291 -0
  85. agentkit/toolkit/integrations/utils/__init__.py +21 -0
  86. agentkit/toolkit/integrations/utils/project_archiver.py +276 -0
  87. agentkit/toolkit/integrations/ve_code_pipeline.py +643 -0
  88. agentkit/toolkit/integrations/ve_cr.py +385 -0
  89. agentkit/toolkit/integrations/ve_iam.py +210 -0
  90. agentkit/toolkit/resources/samples/basic.py +79 -0
  91. agentkit/toolkit/resources/samples/basic_stream.py +100 -0
  92. agentkit/toolkit/resources/samples/customer_support_assistant.py +3 -0
  93. agentkit/toolkit/resources/samples/financial_analyst.py +140 -0
  94. agentkit/toolkit/resources/samples/simple_a2a_veadk.py +32 -0
  95. agentkit/toolkit/resources/samples/simple_app_veadk.py +55 -0
  96. agentkit/toolkit/resources/samples/simple_mcp_veadk.py +50 -0
  97. agentkit/toolkit/resources/templates/Dockerfile.j2 +27 -0
  98. agentkit/toolkit/resources/templates/code-pipeline-tos-cr-step.j2 +52 -0
  99. agentkit/toolkit/workflows/__init__.py +27 -0
  100. agentkit/toolkit/workflows/base.py +87 -0
  101. agentkit/toolkit/workflows/hybird_local_ve_workflow_v1.py +381 -0
  102. agentkit/toolkit/workflows/local_workflow_v1.py +262 -0
  103. agentkit/toolkit/workflows/ve_agentkit_workflow.py +369 -0
  104. agentkit/tools/__init__.py +17 -0
  105. agentkit/tools/tools.py +106 -0
  106. agentkit/tools/tools_all_types.py +337 -0
  107. agentkit/utils/__init__.py +41 -0
  108. agentkit/utils/credential.py +44 -0
  109. agentkit/utils/logging_config.py +366 -0
  110. agentkit/utils/misc.py +70 -0
  111. agentkit/utils/request.py +59 -0
  112. agentkit/utils/template_utils.py +256 -0
  113. agentkit/utils/ve_sign.py +247 -0
  114. agentkit/version.py +15 -0
  115. agentkit_sdk_python-0.1.5.dist-info/METADATA +262 -0
  116. agentkit_sdk_python-0.1.5.dist-info/RECORD +120 -0
  117. agentkit_sdk_python-0.1.5.dist-info/WHEEL +5 -0
  118. agentkit_sdk_python-0.1.5.dist-info/entry_points.txt +2 -0
  119. agentkit_sdk_python-0.1.5.dist-info/licenses/LICENSE +201 -0
  120. agentkit_sdk_python-0.1.5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,381 @@
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
+ from agentkit.toolkit.workflows import Workflow
16
+ from typing import Dict, Any, List, Optional, Tuple
17
+ from rich.console import Console
18
+ from datetime import datetime
19
+ import os
20
+
21
+ from agentkit.toolkit.config import (
22
+ AUTO_CREATE_VE,
23
+ get_config,
24
+ HybridVeAgentkitConfig_v1,
25
+ CommonConfig,
26
+ )
27
+ from agentkit.toolkit.config.auto_prompt import auto_prompt
28
+ from agentkit.toolkit.integrations.services import CRService, CRServiceConfig, DefaultCRConfigCallback
29
+ from agentkit.toolkit.integrations.runner import VeAgentkitRuntimeRunner
30
+
31
+ console = Console()
32
+
33
+
34
+
35
+
36
+
37
+ class HybridVeAgentkitWorkflow_v1(Workflow):
38
+ def prompt_for_config(self, current_config: Dict[str, Any] = None) -> Dict[str, Any]:
39
+ agent_config = get_config()
40
+ common_config = agent_config.get_common_config()
41
+ # 兼容旧字段名
42
+ if current_config.get("cr_instance_name") is None or current_config["cr_instance_name"] == AUTO_CREATE_VE or current_config["cr_instance_name"] == "":
43
+ # 也检查旧字段名
44
+ if current_config.get("ve_cr_instance_name"):
45
+ current_config["cr_instance_name"] = current_config["ve_cr_instance_name"]
46
+ else:
47
+ current_config["cr_instance_name"] = CRService.default_cr_instance_name_template()
48
+ if current_config.get("cr_repo_name") is None or current_config["cr_repo_name"] == AUTO_CREATE_VE or current_config["cr_repo_name"] == "":
49
+ if current_config.get("ve_cr_repo_name"):
50
+ current_config["cr_repo_name"] = current_config["ve_cr_repo_name"]
51
+ else:
52
+ current_config["cr_repo_name"] = common_config.agent_name
53
+
54
+ ve_config = auto_prompt.generate_config(HybridVeAgentkitConfig_v1, current_config)
55
+ return ve_config
56
+
57
+ def build(self, config: Dict[str, Any]) -> bool:
58
+ """Build the agent image using LocalDockerBuilder."""
59
+ try:
60
+ from agentkit.toolkit.integrations.builder.local_docker_builder import LocalDockerBuilder, LocalDockerBuilderConfig, LocalDockerBuilderResult
61
+ except ImportError as e:
62
+ console.print(f"ImportError: {e}")
63
+ console.print("[red]错误: 缺少Docker相关依赖,请安装agentkit[docker] extras[/red]")
64
+ return False
65
+ try:
66
+ hybrid_ve_config = HybridVeAgentkitConfig_v1.from_dict(config)
67
+ # if hybrid_ve_config.cr_image_full_url:
68
+ # console.print(f"[yellow]⚠️ 已配置远程镜像: {hybrid_ve_config.cr_image_full_url},将跳过本地构建[/yellow]")
69
+ # return True
70
+
71
+ agent_config = get_config()
72
+ common_config = agent_config.get_common_config()
73
+
74
+ # 使用LocalDockerBuilderConfig类构建配置,避免硬编码字符串
75
+ builder_config_obj = LocalDockerBuilderConfig(
76
+ common_config=common_config,
77
+ image_name=common_config.agent_name or "agentkit-app",
78
+ image_tag=hybrid_ve_config.image_tag
79
+ )
80
+ builder_config = builder_config_obj.to_dict()
81
+
82
+ builder = LocalDockerBuilder()
83
+ success, build_result = builder.build(builder_config)
84
+ result_obj = LocalDockerBuilderResult.from_dict(build_result)
85
+ if success:
86
+ hybrid_ve_config.full_image_name = result_obj.full_image_name
87
+ hybrid_ve_config.image_id = result_obj.image_id
88
+ hybrid_ve_config.build_timestamp = result_obj.build_timestamp
89
+ console.print(f"[green]✅ 镜像构建成功, 镜像名称: {hybrid_ve_config.full_image_name}, 镜像ID: {hybrid_ve_config.image_id}, 构建时间: {hybrid_ve_config.build_timestamp}[/green]")
90
+ agent_config.update_workflow_config("hybrid", hybrid_ve_config.to_persist_dict())
91
+ return True
92
+ else:
93
+ build_logs = result_obj.build_logs or []
94
+ console.print(f"[red]❌ 镜像构建失败[/red]")
95
+ if build_logs:
96
+ # build_logs is a list, display each line
97
+ if isinstance(build_logs, list):
98
+ for log_line in build_logs:
99
+ if log_line.strip():
100
+ console.print(f"[red]{log_line}[/red]")
101
+ else:
102
+ console.print(f"[red]{build_logs}[/red]")
103
+ return False
104
+
105
+ except Exception as e:
106
+ console.print(f"[red]构建过程中发生错误: {str(e)}[/red]")
107
+ return False
108
+
109
+ def deploy(self, config: Dict[str, Any]) -> bool:
110
+ """简化后的主部署函数 - 仅负责流程编排"""
111
+ try:
112
+ hybrid_ve_config = HybridVeAgentkitConfig_v1.from_dict(config)
113
+ agent_config = get_config()
114
+ common_config = agent_config.get_common_config()
115
+
116
+ # 1. 镜像准备阶段
117
+ if not self._prepare_and_push_image(hybrid_ve_config, common_config):
118
+ return False
119
+
120
+ # 2. Runtime 部署阶段
121
+ return self._deploy_runtime(hybrid_ve_config, common_config)
122
+
123
+ except Exception as e:
124
+ console.print(f"[red]部署失败: {str(e)}[/red]")
125
+ return False
126
+
127
+ def _prepare_and_push_image(self, config: HybridVeAgentkitConfig_v1, common_config: CommonConfig) -> bool:
128
+ """镜像准备和推送"""
129
+ # 如果有远程镜像,但没有本地镜像
130
+ if config.cr_image_full_url and not self._check_local_image(config, common_config):
131
+ return True
132
+
133
+ if not self._check_local_image(config, common_config):
134
+ return False
135
+
136
+ return self._push_image_to_cr(config, common_config)
137
+
138
+ def _check_local_image(self, config: HybridVeAgentkitConfig_v1, common_config: CommonConfig) -> bool:
139
+ """检查本地镜像"""
140
+ try:
141
+ from agentkit.toolkit.integrations.container import DockerManager
142
+ except ImportError:
143
+ console.print("[red]错误: 缺少Docker相关依赖[/red]")
144
+ return False
145
+
146
+ docker_manager = DockerManager()
147
+ image_exists, image_info, actual_image_id = docker_manager.check_image_exists(
148
+ config.full_image_name or f"{common_config.agent_name or 'agentkit-app'}:{config.image_tag}",
149
+ config.image_id
150
+ )
151
+
152
+ if not image_exists:
153
+ console.print(f"[red]❌ 镜像不存在,请先运行 build 命令[/red]")
154
+ return False
155
+
156
+ # 更新镜像ID
157
+ config.image_id = actual_image_id
158
+ return True
159
+
160
+ def _push_image_to_cr(self, config: HybridVeAgentkitConfig_v1, common_config: CommonConfig) -> bool:
161
+ """推送镜像到CR - 使用新的CR服务"""
162
+ # 创建CR配置回调
163
+ def config_updater(workflow_name: str, cr_config_dict: Dict[str, Any]) -> None:
164
+ """配置更新回调"""
165
+ # 将CR配置同步到工作流配置
166
+ if "instance_name" in cr_config_dict:
167
+ config.cr_instance_name = cr_config_dict["instance_name"]
168
+ if "namespace_name" in cr_config_dict:
169
+ config.cr_namespace_name = cr_config_dict["namespace_name"]
170
+ if "repo_name" in cr_config_dict:
171
+ config.cr_repo_name = cr_config_dict["repo_name"]
172
+ if "image_full_url" in cr_config_dict:
173
+ config.cr_image_full_url = cr_config_dict["image_full_url"]
174
+
175
+ # 更新工作流配置
176
+ get_config().update_workflow_config("hybrid", config.to_persist_dict())
177
+
178
+ # 创建CR服务配置
179
+ cr_service_config = CRServiceConfig(
180
+ instance_name=config.cr_instance_name,
181
+ namespace_name=config.cr_namespace_name,
182
+ repo_name=config.cr_repo_name,
183
+ image_full_url=config.cr_image_full_url
184
+ )
185
+
186
+ # 创建CR服务
187
+ cr_service = CRService(config_callback=DefaultCRConfigCallback(config_updater=config_updater))
188
+
189
+ # 确保CR资源存在
190
+ cr_result = cr_service.ensure_cr_resources(cr_service_config, common_config)
191
+ if not cr_result.success:
192
+ console.print(f"[red]❌ CR资源准备失败: {cr_result.error}[/red]")
193
+ return False
194
+
195
+ # 确保公网访问
196
+ public_result = cr_service.ensure_public_endpoint(cr_service_config)
197
+ if not public_result.success:
198
+ console.print(f"[red]❌ 公网访问配置失败: {public_result.error}[/red]")
199
+ return False
200
+
201
+ # 登录并推送镜像
202
+ success, remote_image_full_url = cr_service.login_and_push_image(
203
+ cr_service_config,
204
+ config.image_id,
205
+ config.image_tag,
206
+ cr_result.namespace_name
207
+ )
208
+
209
+ if success:
210
+ config.cr_image_full_url = remote_image_full_url
211
+ get_config().update_workflow_config("hybrid", config.to_persist_dict())
212
+ return True
213
+ else:
214
+ return False
215
+
216
+ # 原有的CR相关方法已经移除,逻辑已迁移到CRService中
217
+
218
+ def _deploy_runtime(self, config: HybridVeAgentkitConfig_v1, common_config) -> bool:
219
+ """部署Runtime - 使用VeAgentkitRuntimeRunner"""
220
+ try:
221
+ # 合并应用级和 Workflow 级环境变量
222
+ from agentkit.toolkit.config import merge_runtime_envs
223
+ merged_envs = merge_runtime_envs(common_config, config.to_dict())
224
+
225
+ # 创建Runner配置
226
+ runner_config = {
227
+ "common_config": common_config.to_dict(),
228
+ "runtime_id": config.runtime_id or AUTO_CREATE_VE,
229
+ "runtime_name": config.runtime_name,
230
+ "runtime_role_name": config.runtime_role_name,
231
+ "runtime_apikey": config.runtime_apikey,
232
+ "runtime_apikey_name": config.runtime_apikey_name,
233
+ "runtime_endpoint": config.runtime_endpoint,
234
+ "runtime_envs": merged_envs,
235
+ "image_url": config.cr_image_full_url
236
+ }
237
+
238
+ # 使用Runner部署
239
+ runner = VeAgentkitRuntimeRunner()
240
+ success, result = runner.deploy(runner_config)
241
+
242
+ if success:
243
+ # 更新配置
244
+ config.runtime_id = result.get("runtime_id", config.runtime_id)
245
+ config.runtime_name = result.get("runtime_name", config.runtime_name)
246
+ config.runtime_endpoint = result.get("runtime_endpoint", config.runtime_endpoint)
247
+ config.runtime_apikey = result.get("runtime_apikey", config.runtime_apikey)
248
+ config.runtime_apikey_name = result.get("runtime_apikey_name", config.runtime_apikey_name)
249
+ config.runtime_role_name = result.get("runtime_role_name", config.runtime_role_name)
250
+
251
+ # 保存配置
252
+ agent_config = get_config()
253
+ agent_config.update_workflow_config("hybrid", config.to_persist_dict())
254
+
255
+ console.print(f"[green]✅ Runtime部署成功: {result['message']}[/green]")
256
+ return True
257
+ else:
258
+ console.print(f"[red]❌ Runtime部署失败: {result.get('error', '未知错误')}[/red]")
259
+ return False
260
+
261
+ except Exception as e:
262
+ console.print(f"[red]❌ Runtime部署异常: {str(e)}[/red]")
263
+ return False
264
+
265
+ def invoke(self, config: Dict[str, Any], args: Dict[str, Any]) -> Tuple[bool, Any]:
266
+ """Invoke the workflow - 使用VeAgentkitRuntimeRunner.
267
+ Args:
268
+ config (Dict[str, Any]): The configuration of the workflow.
269
+ Returns:
270
+ bool: True if the invocation was successful, False otherwise.
271
+ """
272
+ hybrid_ve_config = HybridVeAgentkitConfig_v1.from_dict(config)
273
+ if not hybrid_ve_config.runtime_id:
274
+ console.print(f"❌ 暂未部署到Agentkit Platform")
275
+ return False, None
276
+ try:
277
+ # 创建Runner配置
278
+ runner_config = {
279
+ "common_config": {},
280
+ "runtime_id": hybrid_ve_config.runtime_id,
281
+ "runtime_endpoint": hybrid_ve_config.runtime_endpoint,
282
+ "runtime_apikey": hybrid_ve_config.runtime_apikey
283
+ }
284
+ payload = args.get("payload", {"prompt": "北京天气怎么样"})
285
+ if isinstance(payload, str):
286
+ payload = json.loads(payload)
287
+ headers = args.get("headers", {"user_id": "agentkit_user", "session_id": "agentkit_sample_session"})
288
+ if isinstance(headers, str):
289
+ headers = json.loads(headers)
290
+ # 使用Runner调用
291
+ runner = VeAgentkitRuntimeRunner()
292
+ success, result = runner.invoke(runner_config, payload, headers)
293
+ if success:
294
+ return True, result
295
+ else:
296
+ console.print(f"[red]❌ Runtime调用失败: {result}[/red]")
297
+ return False, None
298
+ except Exception as e:
299
+ console.print(f"[red]❌ 调用Runtime异常: {str(e)}[/red]")
300
+ return False, None
301
+
302
+
303
+ def status(self, config: Dict[str, Any] = None) -> Dict[str, Any]:
304
+ """Get the status of the workflow - 使用VeAgentkitRuntimeRunner."""
305
+ hybrid_ve_config = HybridVeAgentkitConfig_v1.from_dict(config)
306
+ if not hybrid_ve_config.runtime_id or hybrid_ve_config.runtime_id == AUTO_CREATE_VE:
307
+ console.print(f"❌ 暂未部署到Agentkit Platform")
308
+ return {}
309
+ try:
310
+ # 创建Runner配置
311
+ runner_config = {
312
+ "common_config": {},
313
+ "runtime_id": hybrid_ve_config.runtime_id,
314
+ "runtime_endpoint": hybrid_ve_config.runtime_endpoint,
315
+ "runtime_apikey": hybrid_ve_config.runtime_apikey
316
+ }
317
+ # 使用Runner获取状态
318
+ runner = VeAgentkitRuntimeRunner()
319
+ status_info = runner.status(runner_config)
320
+ # 控制台输出
321
+ if status_info.get("status") == "Ready":
322
+ console.print(f"[green]✅ Runtime状态为Ready, Endpoint: {status_info.get('endpoint')}[/green]")
323
+ else:
324
+ console.print(f"[yellow]当前Runtime状态: {status_info.get('status')},状态异常[/yellow]")
325
+ return status_info
326
+ except Exception as e:
327
+ console.print(f"[red]❌ 获取Runtime状态失败: {str(e)}[/red]")
328
+ return {"status": "error", "message": str(e)}
329
+
330
+
331
+ def stop(self) -> None:
332
+ """Stop the workflow - 使用VeAgentkitRuntimeRunner."""
333
+ agent_config = get_config()
334
+ config = agent_config.get_workflow_config("hybrid")
335
+ hybrid_ve_config = HybridVeAgentkitConfig_v1.from_dict(config)
336
+ if not hybrid_ve_config.runtime_id or hybrid_ve_config.runtime_id == AUTO_CREATE_VE:
337
+ console.print(f"[yellow]⚠️ 未配置Runtime ID,无需停止[/yellow]")
338
+ return
339
+ try:
340
+ # 创建Runner配置
341
+ runner_config = {
342
+ "common_config": {},
343
+ "runtime_id": hybrid_ve_config.runtime_id
344
+ }
345
+ # 使用Runner停止
346
+ runner = VeAgentkitRuntimeRunner()
347
+ success = runner.stop(runner_config)
348
+ if success:
349
+ console.print(f"[green]✅ Runtime停止成功[/green]")
350
+ else:
351
+ console.print(f"[red]❌ Runtime停止失败[/red]")
352
+ except Exception as e:
353
+ console.print(f"[red]❌ 停止Runtime异常: {str(e)}[/red]")
354
+
355
+ def destroy(self) -> None:
356
+ """Stop and destroy the workflow resources - 使用VeAgentkitRuntimeRunner."""
357
+ agent_config = get_config()
358
+ config = agent_config.get_workflow_config("hybrid")
359
+ hybrid_ve_config = HybridVeAgentkitConfig_v1.from_dict(config)
360
+ if not hybrid_ve_config.runtime_id or hybrid_ve_config.runtime_id == AUTO_CREATE_VE:
361
+ console.print(f"[yellow]⚠️ 未配置Runtime ID,无需销毁[/yellow]")
362
+ return
363
+ try:
364
+ # 创建Runner配置
365
+ runner_config = {
366
+ "common_config": {},
367
+ "runtime_id": hybrid_ve_config.runtime_id
368
+ }
369
+ # 使用Runner销毁
370
+ runner = VeAgentkitRuntimeRunner()
371
+ success = runner.destroy(runner_config)
372
+ if success:
373
+ # 清除配置中的Runtime信息
374
+ hybrid_ve_config.runtime_id = ""
375
+ hybrid_ve_config.runtime_endpoint = ""
376
+ hybrid_ve_config.runtime_apikey = ""
377
+ agent_config.update_workflow_config("hybrid", hybrid_ve_config.to_persist_dict())
378
+ else:
379
+ console.print(f"[red]❌ Runtime销毁失败[/red]")
380
+ except Exception as e:
381
+ console.print(f"[red]❌ 销毁Runtime异常: {str(e)}[/red]")
@@ -0,0 +1,262 @@
1
+
2
+ # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import typer
17
+ import os
18
+ from datetime import datetime
19
+ from typing import Any, Dict, List, Tuple
20
+ from pathlib import Path
21
+
22
+ from agentkit.toolkit.workflows import Workflow
23
+ from rich.console import Console
24
+ from agentkit.toolkit.config import get_config, CommonConfig, LocalDockerConfig_v1
25
+
26
+ console = Console()
27
+
28
+
29
+ class LocalWorkflow_v1(Workflow):
30
+ """Local Docker workflow implementation"""
31
+
32
+ def prompt_for_config(self, current_config: Dict[str, Any] = None) -> Dict[str, Any]:
33
+ """Generate interactive configuration based on dataclass"""
34
+ from agentkit.toolkit.config.auto_prompt import generate_config_from_dataclass
35
+
36
+ if current_config is None:
37
+ current_config = {}
38
+
39
+ return generate_config_from_dataclass(LocalDockerConfig_v1, current_config)
40
+
41
+ def build(self, config: Dict[str, Any]) -> bool:
42
+ """Build the agent image using LocalDockerBuilder."""
43
+ try:
44
+ from agentkit.toolkit.integrations.builder.local_docker_builder import (
45
+ LocalDockerBuilder, LocalDockerBuilderConfig, LocalDockerBuilderResult
46
+ )
47
+ except ImportError:
48
+ console.print("[red]Error: Docker dependencies missing, install agentkit[docker] extras[/red]")
49
+ return False
50
+
51
+ try:
52
+ agent_config = get_config()
53
+ common_config = agent_config.get_common_config()
54
+ docker_config = LocalDockerConfig_v1.from_dict(config)
55
+
56
+ builder_config = LocalDockerBuilderConfig(
57
+ common_config=common_config,
58
+ image_name=common_config.agent_name or "agentkit-app",
59
+ image_tag=docker_config.image_tag
60
+ ).to_dict()
61
+
62
+ builder = LocalDockerBuilder()
63
+ success, build_result = builder.build(builder_config)
64
+
65
+ if success:
66
+ result = LocalDockerBuilderResult.from_dict(build_result)
67
+ docker_config.full_image_name = result.full_image_name
68
+ docker_config.image_id = result.image_id
69
+ docker_config.build_timestamp = result.build_timestamp
70
+ agent_config.update_workflow_config("local", docker_config.to_persist_dict())
71
+ console.print(f"[green]✅ Build completed: {result.full_image_name}[/green]")
72
+ return True
73
+ else:
74
+ result = LocalDockerBuilderResult.from_dict(build_result)
75
+ console.print(f"[red]❌ Build failed[/red]")
76
+ if result.build_logs:
77
+ # build_logs is a list, display each line
78
+ if isinstance(result.build_logs, list):
79
+ for log_line in result.build_logs:
80
+ if log_line.strip():
81
+ console.print(f"[red]{log_line}[/red]")
82
+ else:
83
+ console.print(f"[red]{result.build_logs}[/red]")
84
+ return False
85
+
86
+ except Exception as e:
87
+ console.print(f"[red]Build error: {str(e)}[/red]")
88
+ return False
89
+
90
+ def deploy(self, config: Dict[str, Any]) -> bool:
91
+ """Deploy agent image to local Docker container"""
92
+ try:
93
+ from agentkit.toolkit.integrations.runner.local_docker_runner import (
94
+ LocalDockerRunner, LocalDockerRunnerConfig, LocalDockerDeployResult
95
+ )
96
+ except ImportError:
97
+ console.print("[red]Error: Docker dependencies missing, install agentkit[docker] extras[/red]")
98
+ return False
99
+
100
+ try:
101
+ docker_config = LocalDockerConfig_v1.from_dict(config)
102
+ agent_config = get_config()
103
+ common_config = agent_config.get_common_config()
104
+
105
+ runner_config = self._build_runner_config(docker_config, common_config)
106
+ runner = LocalDockerRunner()
107
+ success, deploy_result = runner.deploy(runner_config)
108
+
109
+ result = LocalDockerDeployResult.from_dict(deploy_result)
110
+
111
+ if success:
112
+ docker_config.container_id = result.container_id
113
+ docker_config.container_name = result.container_name
114
+ docker_config.deploy_timestamp = result.deploy_timestamp
115
+ agent_config.update_workflow_config("local", docker_config.to_persist_dict())
116
+ console.print(f"[green]✅ Container deployed successfully: {result.container_name}[/green]")
117
+ return True
118
+ else:
119
+ error_msg = result.error_message or "Deployment failed"
120
+ console.print(f"[red]❌ Container deployment failed: {error_msg}[/red]")
121
+ return False
122
+
123
+ except Exception as e:
124
+ console.print(f"[red]Deployment error: {str(e)}[/red]")
125
+ return False
126
+
127
+ def invoke(self, config: Dict[str, Any] = None, args: Dict[str, Any] = None) -> Tuple[bool, Any]:
128
+ """Invoke the workflow with given configuration and arguments."""
129
+ try:
130
+ from agentkit.toolkit.integrations.runner.local_docker_runner import LocalDockerRunner, LocalDockerRunnerConfig
131
+ except ImportError:
132
+ console.print("[red]Error: Docker dependencies missing, install agentkit[docker] extras[/red]")
133
+ return False, None
134
+
135
+ try:
136
+ agent_config = get_config()
137
+ common_config = agent_config.get_common_config()
138
+ docker_config = LocalDockerConfig_v1.from_dict(config)
139
+
140
+ payload = args.get("payload") if args else None
141
+ headers = args.get("headers") if args else None
142
+
143
+ runner_config = self._build_runner_config(docker_config, common_config)
144
+ runner = LocalDockerRunner()
145
+ success, response_data = runner.invoke(runner_config, payload, headers)
146
+
147
+ if success:
148
+ return True, response_data
149
+ else:
150
+ console.print(f"[red]❌ Invocation failed: {response_data}[/red]")
151
+ return False, None
152
+
153
+ except Exception as e:
154
+ console.print(f"[red]Invocation error: {str(e)}[/red]")
155
+ return False, None
156
+
157
+ def status(self, config: Dict[str, Any] = None) -> Dict[str, Any]:
158
+ """Get local Docker deployment status"""
159
+ try:
160
+ from agentkit.toolkit.integrations.runner.local_docker_runner import LocalDockerRunner, LocalDockerRunnerConfig
161
+ except ImportError:
162
+ console.print("[red]Error: Docker dependencies missing, install agentkit[docker] extras[/red]")
163
+ return {
164
+ 'error': 'Docker dependencies missing',
165
+ 'project_name': None,
166
+ 'image_name': None,
167
+ 'build': {'exists': False, 'message': 'Query failed'},
168
+ 'deploy': {'exists': False, 'message': 'Query failed'},
169
+ 'system': {'docker_available': False, 'timestamp': datetime.now().isoformat()}
170
+ }
171
+
172
+ try:
173
+ agent_config = get_config()
174
+ if config is None:
175
+ config = agent_config.get_workflow_config("local")
176
+
177
+ docker_config = LocalDockerConfig_v1.from_dict(config)
178
+ common_config = agent_config.get_common_config()
179
+ runner_config = self._build_runner_config(docker_config, common_config)
180
+
181
+ runner = LocalDockerRunner()
182
+ return runner.status(runner_config)
183
+
184
+ except Exception as e:
185
+ console.print(f"[red]Status query failed: {str(e)}[/red]")
186
+ return {
187
+ 'error': str(e),
188
+ 'project_name': None,
189
+ 'image_name': None,
190
+ 'build': {'exists': False, 'message': 'Query failed'},
191
+ 'deploy': {'exists': False, 'message': 'Query failed'},
192
+ 'system': {'docker_available': False, 'timestamp': datetime.now().isoformat()}
193
+ }
194
+
195
+ def _build_runner_config(self, docker_config: LocalDockerConfig_v1, common_config: CommonConfig) -> Dict[str, Any]:
196
+ """Build LocalDockerRunner configuration object"""
197
+ from agentkit.toolkit.integrations.runner.local_docker_runner import LocalDockerRunnerConfig
198
+ from agentkit.toolkit.config import merge_runtime_envs
199
+
200
+ # 合并应用级和 Workflow 级环境变量
201
+ merged_envs = merge_runtime_envs(common_config, docker_config.to_dict())
202
+
203
+ return LocalDockerRunnerConfig(
204
+ common_config=common_config,
205
+ invoke_port=docker_config.invoke_port,
206
+ full_image_name=docker_config.full_image_name,
207
+ image_name=common_config.agent_name or "agentkit-app",
208
+ image_tag=docker_config.image_tag,
209
+ container_name=docker_config.container_name,
210
+ container_id=docker_config.container_id,
211
+ image_id=docker_config.image_id,
212
+ environment=merged_envs,
213
+ ports=getattr(docker_config, 'ports', None),
214
+ volumes=getattr(docker_config, 'volumes', None),
215
+ restart_policy=getattr(docker_config, 'restart_policy', None),
216
+ memory_limit=getattr(docker_config, 'memory_limit', None),
217
+ cpu_limit=getattr(docker_config, 'cpu_limit', None)
218
+ ).to_dict()
219
+
220
+ def stop(self) -> None:
221
+ """Stop the workflow."""
222
+ pass
223
+
224
+ def destroy(self) -> None:
225
+ """Stop and destroy workflow resources"""
226
+ try:
227
+ from agentkit.toolkit.config import get_config
228
+ try:
229
+ from agentkit.toolkit.integrations.runner.local_docker_runner import LocalDockerRunner, LocalDockerRunnerConfig
230
+ except ImportError:
231
+ console.print("[red]Error: Docker dependencies missing, install agentkit[docker] extras[/red]")
232
+ return
233
+
234
+ agent_config = get_config()
235
+ config = agent_config.get_workflow_config("local")
236
+ docker_config = LocalDockerConfig_v1.from_dict(config)
237
+ common_config = agent_config.get_common_config()
238
+
239
+ runner_config = self._build_runner_config(docker_config, common_config)
240
+ runner = LocalDockerRunner()
241
+ runner.destroy(runner_config)
242
+
243
+ # Clear configuration state
244
+ docker_config.container_id = None
245
+ docker_config.deploy_timestamp = None
246
+ docker_config.image_id = None
247
+ docker_config.build_timestamp = None
248
+ docker_config.full_image_name = None
249
+
250
+ agent_config.update_workflow_config("local", docker_config.to_persist_dict())
251
+
252
+ # Clean up Dockerfile
253
+ try:
254
+ dockerfile_path = Path.cwd() / "Dockerfile"
255
+ if dockerfile_path.exists():
256
+ dockerfile_path.unlink()
257
+ except Exception:
258
+ pass
259
+
260
+ except Exception as e:
261
+ console.print(f"[red]❌ Destruction error: {str(e)}[/red]")
262
+ raise