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
agentkit/__init__.py ADDED
@@ -0,0 +1,23 @@
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
+ # Note: BaseAgentkitClient and ApiConfig are internal infrastructure classes.
16
+ # Users should use the high-level service clients instead:
17
+ # - from agentkit.memory import AgentkitMemory
18
+ # - from agentkit.knowledge import AgentkitKnowledge
19
+ # - from agentkit.mcp import AgentkitMCP
20
+ # - from agentkit.runtime import AgentkitRuntime
21
+ # - from agentkit.tools import AgentkitTools
22
+
23
+ __all__ = []
@@ -0,0 +1,58 @@
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 typing import TYPE_CHECKING
16
+
17
+ if TYPE_CHECKING:
18
+ from agentkit.apps.a2a_app.a2a_app import AgentkitA2aApp
19
+ from agentkit.apps.agent_server_app.agent_server_app import AgentkitAgentServerApp
20
+ from agentkit.apps.mcp_app.mcp_app import AgentkitMCPApp
21
+ from agentkit.apps.simple_app.simple_app import AgentkitSimpleApp
22
+
23
+
24
+ def __getattr__(
25
+ name,
26
+ ) -> (
27
+ type["AgentkitA2aApp"]
28
+ | type["AgentkitMCPApp"]
29
+ | type["AgentkitSimpleApp"]
30
+ | type["AgentkitAgentServerApp"]
31
+ ):
32
+ if name == "AgentkitA2aApp":
33
+ from agentkit.apps.a2a_app.a2a_app import AgentkitA2aApp
34
+
35
+ return AgentkitA2aApp
36
+ if name == "AgentkitMCPApp":
37
+ from agentkit.apps.mcp_app.mcp_app import AgentkitMCPApp
38
+
39
+ return AgentkitMCPApp
40
+ if name == "AgentkitSimpleApp":
41
+ from agentkit.apps.simple_app.simple_app import AgentkitSimpleApp
42
+
43
+ return AgentkitSimpleApp
44
+ if name == "AgentkitAgentServerApp":
45
+ from agentkit.apps.agent_server_app.agent_server_app import (
46
+ AgentkitAgentServerApp,
47
+ )
48
+
49
+ return AgentkitAgentServerApp
50
+ raise AttributeError(f"module 'agentkit.apps' has no attribute '{name}'")
51
+
52
+
53
+ __all__ = [
54
+ "AgentkitA2aApp",
55
+ "AgentkitMCPApp",
56
+ "AgentkitSimpleApp",
57
+ "AgentkitAgentServerApp",
58
+ ]
@@ -0,0 +1,13 @@
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.
@@ -0,0 +1,134 @@
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 logging
16
+ import time
17
+ from typing import Callable, override
18
+
19
+ import uvicorn
20
+ from a2a.server.agent_execution import AgentExecutor
21
+ from a2a.server.agent_execution.context import RequestContext
22
+ from a2a.server.apps import A2AStarletteApplication
23
+ from a2a.server.events.event_queue import EventQueue
24
+ from a2a.server.request_handlers import DefaultRequestHandler
25
+ from a2a.server.tasks import InMemoryTaskStore
26
+ from a2a.server.tasks.task_store import TaskStore
27
+ from a2a.types import AgentCard
28
+
29
+ from agentkit.apps.base_app import BaseAgentkitApp
30
+ from agentkit.apps.a2a_app.telemetry import telemetry
31
+
32
+ logger = logging.getLogger(__name__)
33
+
34
+
35
+ def _wrap_agent_executor_execute_func(execute_func: Callable) -> Callable:
36
+ async def wrapper(*args, **kwargs):
37
+ executor_instance: AgentExecutor = args[0]
38
+ context: RequestContext = args[1]
39
+ event_queue: EventQueue = args[2]
40
+
41
+ with telemetry.tracer.start_as_current_span(name="a2a_invocation") as span:
42
+ exception = None
43
+ try:
44
+ result = await execute_func(
45
+ executor_instance, context=context, event_queue=event_queue
46
+ )
47
+
48
+ except Exception as e:
49
+ logger.error("Invoke agent execute function failed: %s", e)
50
+ exception = e
51
+ raise e
52
+ finally:
53
+ # handler trace span and metrics
54
+ telemetry.trace_a2a_agent(
55
+ execute_func,
56
+ span,
57
+ context,
58
+ result,
59
+ exception,
60
+ )
61
+
62
+ return result
63
+
64
+ return wrapper
65
+
66
+
67
+ class AgentkitA2aApp(BaseAgentkitApp):
68
+ def __init__(self) -> None:
69
+ super().__init__()
70
+
71
+ self._agent_executor: AgentExecutor | None = None
72
+ self._task_store: TaskStore | None = None
73
+
74
+ def agent_executor(self, **kwargs) -> Callable:
75
+ """Wrap an AgentExecutor class, init it, then bind it to the app instance."""
76
+
77
+ def wrapper(cls: type) -> type[AgentExecutor]:
78
+ if not issubclass(cls, AgentExecutor):
79
+ raise TypeError(
80
+ f"{cls.__name__} must inherit from `a2a.server.agent_execution.AgentExecutor`"
81
+ )
82
+
83
+ if self._agent_executor:
84
+ raise RuntimeError("An executor is already bound to this app instance.")
85
+
86
+ # Wrap the execute method for intercepting context and event_queue
87
+ cls.execute = _wrap_agent_executor_execute_func(cls.execute)
88
+
89
+ # Initialize and bind the executor instance
90
+ self._agent_executor = cls(**kwargs)
91
+
92
+ return cls
93
+
94
+ return wrapper
95
+
96
+ def task_store(self, **kwargs) -> Callable:
97
+ """Wrap a TaskStore class, init it, then bind it to the app instance."""
98
+
99
+ def wrapper(cls: type) -> type[TaskStore]:
100
+ if not issubclass(cls, TaskStore):
101
+ raise TypeError(
102
+ f"{cls.__name__} must inherit from `a2a.server.tasks.task_store.TaskStore`"
103
+ )
104
+
105
+ if self._task_store:
106
+ raise RuntimeError(
107
+ "A task store is already bound to this app instance."
108
+ )
109
+
110
+ self._task_store = cls(**kwargs)
111
+ return cls
112
+
113
+ return wrapper
114
+
115
+ @override
116
+ def run(self, agent_card: AgentCard, host: str, port: int = 8000):
117
+ if not self._agent_executor:
118
+ raise RuntimeError(
119
+ "At least one executor should be provided via `@agent_executor(...)`."
120
+ )
121
+ if not self._task_store:
122
+ logger.warning(
123
+ "No task store provided. You can provide a task store via `@task_store(...)`. Using in-memory task store instead."
124
+ )
125
+ self._task_store = InMemoryTaskStore()
126
+
127
+ a2a_app = A2AStarletteApplication(
128
+ agent_card=agent_card,
129
+ http_handler=DefaultRequestHandler(
130
+ agent_executor=self._agent_executor, task_store=self._task_store
131
+ ),
132
+ ).build()
133
+
134
+ uvicorn.run(a2a_app, host=host, port=port)
@@ -0,0 +1,119 @@
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
+
16
+ import logging
17
+ import time
18
+ from typing import Callable
19
+
20
+ from opentelemetry import trace
21
+ from opentelemetry.trace import get_tracer
22
+ from opentelemetry.metrics import get_meter
23
+ from opentelemetry.trace.span import Span
24
+ from a2a.server.agent_execution.context import RequestContext
25
+ from google.adk.a2a.converters.request_converter import _get_user_id
26
+
27
+ from agentkit.apps.utils import safe_serialize_to_json_string
28
+
29
+ _GEN_AI_CLIENT_OPERATION_DURATION_BUCKETS = [
30
+ 0.01,
31
+ 0.02,
32
+ 0.04,
33
+ 0.08,
34
+ 0.16,
35
+ 0.32,
36
+ 0.64,
37
+ 1.28,
38
+ 2.56,
39
+ 5.12,
40
+ 10.24,
41
+ 20.48,
42
+ 40.96,
43
+ 81.92,
44
+ 163.84,
45
+ ]
46
+
47
+ logger = logging.getLogger("agentkit." + __name__)
48
+
49
+ class Telemetry:
50
+ def __init__(self):
51
+ self.tracer = get_tracer("agentkit.a2a_app")
52
+ self.meter = get_meter("agentkit.a2a_app")
53
+ self.latency_histogram = self.meter.create_histogram(
54
+ name="agentkit_runtime_operation_latency",
55
+ description="operation latency",
56
+ unit="s",
57
+ explicit_bucket_boundaries_advisory=_GEN_AI_CLIENT_OPERATION_DURATION_BUCKETS,
58
+ )
59
+
60
+
61
+ def trace_a2a_agent(
62
+ self,
63
+ func: Callable,
64
+ span: Span,
65
+ request: RequestContext,
66
+ result: any,
67
+ exception: Exception,
68
+ ) -> None:
69
+ """Get current span and set required attributes."""
70
+ trace_id = span.get_span_context().trace_id
71
+ span_id = span.get_span_context().span_id
72
+ logger.debug(f"Set attributes for span with trace_id={trace_id}, span_id={span_id}")
73
+
74
+ # ===============================
75
+ # Set attributes for current span
76
+ # ===============================
77
+
78
+ span.set_attribute(key="gen_ai.system", value="agentkit")
79
+
80
+ span.set_attribute(key="gen_ai.func_name", value=func.__name__)
81
+
82
+ # TODO: get user_id and session_id, output from event queue
83
+ session_id = request.context_id
84
+ if session_id:
85
+ span.set_attribute(key="gen_ai.session.id", value=session_id)
86
+ user_id = _get_user_id(request)
87
+ if user_id:
88
+ span.set_attribute(key="gen_ai.user.id", value=user_id)
89
+
90
+ span.set_attribute(key="gen_ai.input", value=safe_serialize_to_json_string(request.message.parts))
91
+
92
+ span.set_attribute(key="gen_ai.span.kind", value="a2a_agent")
93
+ span.set_attribute(key="gen_ai.operation.name", value="invoke_agent")
94
+ span.set_attribute(key="gen_ai.operation.type", value="a2a_agent")
95
+ attributes={"gen_ai_operation_name": "invoke_agent", "gen_ai_operation_type": "a2a_agent"}
96
+
97
+ if exception:
98
+ self.handle_exception(span, exception)
99
+ attributes["error_type"] = exception.__class__.__name__
100
+
101
+ # record latency metrics
102
+ if hasattr(span, "start_time") and self.latency_histogram:
103
+ duration = (time.time_ns() - span.start_time) / 1e9 # type: ignore
104
+ self.latency_histogram.record(duration, attributes)
105
+
106
+ @staticmethod
107
+ def handle_exception(span: trace.Span, exception: Exception) -> None:
108
+ status = trace.Status(
109
+ status_code=trace.StatusCode.ERROR,
110
+ # Follow the format in OTEL SDK for description, see:
111
+ # https://github.com/open-telemetry/opentelemetry-python/blob/2b9dcfc5d853d1c10176937a6bcaade54cda1a31/opentelemetry-api/src/opentelemetry/trace/__init__.py#L588 # noqa E501
112
+ description=f"{type(exception).__name__}: {exception}",
113
+ )
114
+ span.set_status(status)
115
+ span.record_exception(exception)
116
+
117
+
118
+ telemetry = Telemetry()
119
+
@@ -0,0 +1,13 @@
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.
@@ -0,0 +1,85 @@
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 typing import override
16
+
17
+ import uvicorn
18
+ from google.adk.agents.base_agent import BaseAgent
19
+ from google.adk.artifacts.in_memory_artifact_service import (
20
+ InMemoryArtifactService,
21
+ )
22
+ from google.adk.auth.credential_service.in_memory_credential_service import (
23
+ InMemoryCredentialService,
24
+ )
25
+ from google.adk.cli.adk_web_server import AdkWebServer
26
+ from google.adk.cli.utils.base_agent_loader import BaseAgentLoader
27
+ from google.adk.evaluation.local_eval_set_results_manager import (
28
+ LocalEvalSetResultsManager,
29
+ )
30
+ from google.adk.evaluation.local_eval_sets_manager import LocalEvalSetsManager
31
+ from google.adk.memory.in_memory_memory_service import InMemoryMemoryService
32
+ from google.adk.sessions.base_session_service import BaseSessionService
33
+ from veadk import Agent
34
+ from veadk.memory.short_term_memory import ShortTermMemory
35
+
36
+ from agentkit.apps.base_app import BaseAgentkitApp
37
+
38
+
39
+ class AgentKitAgentLoader(BaseAgentLoader):
40
+ def __init__(self, agent: BaseAgent) -> None:
41
+ super().__init__()
42
+
43
+ self.agent = agent
44
+
45
+ @override
46
+ def load_agent(self, agent_name: str) -> BaseAgent:
47
+ return self.agent
48
+
49
+ @override
50
+ def list_agents(self) -> list[str]:
51
+ return [self.agent.name]
52
+
53
+
54
+ class AgentkitAgentServerApp(BaseAgentkitApp):
55
+ def __init__(
56
+ self, agent: BaseAgent, short_term_memory: BaseSessionService | ShortTermMemory
57
+ ) -> None:
58
+ super().__init__()
59
+
60
+ _artifact_service = InMemoryArtifactService()
61
+ _credential_service = InMemoryCredentialService()
62
+
63
+ _eval_sets_manager = LocalEvalSetsManager(agents_dir=".")
64
+ _eval_set_results_manager = LocalEvalSetResultsManager(agents_dir=".")
65
+
66
+ self.server = AdkWebServer(
67
+ agent_loader=AgentKitAgentLoader(agent),
68
+ session_service=short_term_memory
69
+ if isinstance(short_term_memory, BaseSessionService)
70
+ else short_term_memory.session_service,
71
+ memory_service=agent.long_term_memory
72
+ if isinstance(agent, Agent) and agent.long_term_memory
73
+ else InMemoryMemoryService(),
74
+ artifact_service=_artifact_service,
75
+ credential_service=_credential_service,
76
+ eval_sets_manager=_eval_sets_manager,
77
+ eval_set_results_manager=_eval_set_results_manager,
78
+ agents_dir=".",
79
+ )
80
+
81
+ self.app = self.server.get_fast_api_app()
82
+
83
+ def run(self, host: str, port: int = 8000) -> None:
84
+ """Run the app with Uvicorn server."""
85
+ uvicorn.run(self.app, host=host, port=port)
@@ -0,0 +1,20 @@
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 abc import ABC, abstractmethod
16
+
17
+
18
+ class BaseAgentkitApp(ABC):
19
+ @abstractmethod
20
+ def run(self, **kwargs): ...
@@ -0,0 +1,13 @@
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.
@@ -0,0 +1,150 @@
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
+
16
+ import inspect
17
+ import logging
18
+ import time
19
+ from functools import wraps
20
+ from typing import Any, Callable, override
21
+
22
+ from fastmcp import FastMCP
23
+ from fastmcp.server.server import Transport
24
+
25
+ from agentkit.apps.base_app import BaseAgentkitApp
26
+ from agentkit.apps.mcp_app.telemetry import telemetry
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ class AgentkitMCPApp(BaseAgentkitApp):
32
+ def __init__(self) -> None:
33
+ super().__init__()
34
+
35
+ self._mcp_server = FastMCP("agentkit.mcp_server")
36
+
37
+ def tool(self, func: Callable) -> Callable:
38
+ if inspect.iscoroutinefunction(func):
39
+
40
+ @wraps(func)
41
+ async def async_wrapper(*args, **kwargs) -> Any:
42
+ # with tracer.start_as_current_span("tool") as span:
43
+ with telemetry.tracer.start_as_current_span(name="tool") as span:
44
+ exception = None
45
+ try:
46
+ result = await func(*args, **kwargs)
47
+
48
+ except Exception as e:
49
+ logger.error("Invoke tool function failed: %s", e)
50
+ exception = e
51
+ raise e
52
+ finally:
53
+ # handler trace span and metrics
54
+ telemetry.trace_tool(
55
+ func,
56
+ span,
57
+ args,
58
+ func_result=result,
59
+ operation_type="mcp_tool",
60
+ exception=exception,
61
+ )
62
+
63
+ return result
64
+
65
+ self._mcp_server.tool(async_wrapper)
66
+ else:
67
+
68
+ @wraps(func)
69
+ def sync_wrapper(*args, **kwargs) -> Any:
70
+ # with tracer.start_as_current_span("tool") as span:
71
+ with telemetry.tracer.start_as_current_span(name="tool") as span:
72
+ exception = None
73
+ try:
74
+ result = func(*args, **kwargs)
75
+ except Exception as e:
76
+ logger.error("Invoke tool function failed: %s", e)
77
+ exception = e
78
+ raise e
79
+ finally:
80
+ telemetry.trace_tool(
81
+ func,
82
+ span,
83
+ args,
84
+ func_result=result,
85
+ operation_type="mcp_tool",
86
+ exception=exception,
87
+ )
88
+ return result
89
+
90
+ self._mcp_server.tool(sync_wrapper)
91
+
92
+ return func
93
+
94
+ def agent_as_a_tool(self, func: Callable) -> Callable:
95
+ if inspect.iscoroutinefunction(func):
96
+
97
+ @wraps(func)
98
+ async def async_wrapper(*args, **kwargs) -> Any:
99
+ with telemetry.tracer.start_as_current_span(name="tool") as span:
100
+ exception = None
101
+ try:
102
+ result = await func(*args, **kwargs)
103
+ except Exception as e:
104
+ logger.error("Invoke tool function failed: %s", e)
105
+ exception = e
106
+ raise e
107
+ finally:
108
+ telemetry.trace_tool(
109
+ func,
110
+ span,
111
+ args=args,
112
+ func_result=result,
113
+ operation_type="agent_mcp_tool",
114
+ exception=exception,
115
+ )
116
+ return result
117
+
118
+ self._mcp_server.tool(async_wrapper)
119
+ else:
120
+
121
+ @wraps(func)
122
+ def sync_wrapper(*args, **kwargs) -> Any:
123
+ with telemetry.tracer.start_as_current_span(name="tool") as span:
124
+ exception = None
125
+ try:
126
+ result = func(*args, **kwargs)
127
+ except Exception as e:
128
+ logger.error("Invoke tool function failed: %s", e)
129
+ exception = e
130
+ raise e
131
+ finally:
132
+ telemetry.trace_tool(
133
+ func,
134
+ span,
135
+ args,
136
+ func_result=result,
137
+ operation_type="agent_mcp_tool",
138
+ exception=exception,
139
+ )
140
+ return result
141
+
142
+ self._mcp_server.tool(sync_wrapper)
143
+
144
+ return func
145
+
146
+ @override
147
+ def run(
148
+ self, host: str, port: int = 8000, transport: Transport = "streamable-http"
149
+ ) -> None:
150
+ self._mcp_server.run(host=host, port=port, transport=transport)