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.
- veadk/__init__.py +37 -0
- veadk/a2a/__init__.py +13 -0
- veadk/a2a/agent_card.py +45 -0
- veadk/a2a/remote_ve_agent.py +390 -0
- veadk/a2a/utils/__init__.py +13 -0
- veadk/a2a/utils/agent_to_a2a.py +170 -0
- veadk/a2a/ve_a2a_server.py +93 -0
- veadk/a2a/ve_agent_executor.py +78 -0
- veadk/a2a/ve_middlewares.py +313 -0
- veadk/a2a/ve_task_store.py +37 -0
- veadk/agent.py +402 -0
- veadk/agent_builder.py +93 -0
- veadk/agents/loop_agent.py +68 -0
- veadk/agents/parallel_agent.py +72 -0
- veadk/agents/sequential_agent.py +64 -0
- veadk/auth/__init__.py +13 -0
- veadk/auth/base_auth.py +22 -0
- veadk/auth/ve_credential_service.py +203 -0
- veadk/auth/veauth/__init__.py +13 -0
- veadk/auth/veauth/apmplus_veauth.py +58 -0
- veadk/auth/veauth/ark_veauth.py +75 -0
- veadk/auth/veauth/base_veauth.py +50 -0
- veadk/auth/veauth/cozeloop_veauth.py +13 -0
- veadk/auth/veauth/opensearch_veauth.py +75 -0
- veadk/auth/veauth/postgresql_veauth.py +75 -0
- veadk/auth/veauth/prompt_pilot_veauth.py +60 -0
- veadk/auth/veauth/speech_veauth.py +54 -0
- veadk/auth/veauth/utils.py +69 -0
- veadk/auth/veauth/vesearch_veauth.py +62 -0
- veadk/auth/veauth/viking_mem0_veauth.py +91 -0
- veadk/cli/__init__.py +13 -0
- veadk/cli/cli.py +58 -0
- veadk/cli/cli_clean.py +87 -0
- veadk/cli/cli_create.py +163 -0
- veadk/cli/cli_deploy.py +233 -0
- veadk/cli/cli_eval.py +215 -0
- veadk/cli/cli_init.py +214 -0
- veadk/cli/cli_kb.py +110 -0
- veadk/cli/cli_pipeline.py +285 -0
- veadk/cli/cli_prompt.py +86 -0
- veadk/cli/cli_update.py +106 -0
- veadk/cli/cli_uploadevalset.py +139 -0
- veadk/cli/cli_web.py +143 -0
- veadk/cloud/__init__.py +13 -0
- veadk/cloud/cloud_agent_engine.py +485 -0
- veadk/cloud/cloud_app.py +475 -0
- veadk/config.py +115 -0
- veadk/configs/__init__.py +13 -0
- veadk/configs/auth_configs.py +133 -0
- veadk/configs/database_configs.py +132 -0
- veadk/configs/model_configs.py +78 -0
- veadk/configs/tool_configs.py +54 -0
- veadk/configs/tracing_configs.py +110 -0
- veadk/consts.py +74 -0
- veadk/evaluation/__init__.py +17 -0
- veadk/evaluation/adk_evaluator/__init__.py +17 -0
- veadk/evaluation/adk_evaluator/adk_evaluator.py +302 -0
- veadk/evaluation/base_evaluator.py +642 -0
- veadk/evaluation/deepeval_evaluator/__init__.py +17 -0
- veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +339 -0
- veadk/evaluation/eval_set_file_loader.py +48 -0
- veadk/evaluation/eval_set_recorder.py +146 -0
- veadk/evaluation/types.py +65 -0
- veadk/evaluation/utils/prometheus.py +196 -0
- veadk/integrations/__init__.py +13 -0
- veadk/integrations/ve_apig/__init__.py +13 -0
- veadk/integrations/ve_apig/ve_apig.py +349 -0
- veadk/integrations/ve_apig/ve_apig_utils.py +332 -0
- veadk/integrations/ve_code_pipeline/__init__.py +13 -0
- veadk/integrations/ve_code_pipeline/ve_code_pipeline.py +431 -0
- veadk/integrations/ve_cozeloop/__init__.py +13 -0
- veadk/integrations/ve_cozeloop/ve_cozeloop.py +96 -0
- veadk/integrations/ve_cr/__init__.py +13 -0
- veadk/integrations/ve_cr/ve_cr.py +220 -0
- veadk/integrations/ve_faas/__init__.py +13 -0
- veadk/integrations/ve_faas/template/cookiecutter.json +15 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/config.yaml.example +6 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/deploy.py +106 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/__init__.py +13 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/agent.py +25 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +202 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +3 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +49 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/__init__.py +14 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/agent.py +27 -0
- veadk/integrations/ve_faas/ve_faas.py +754 -0
- veadk/integrations/ve_faas/ve_faas_utils.py +408 -0
- veadk/integrations/ve_faas/web_template/cookiecutter.json +20 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/config.yaml.example +2 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/deploy.py +44 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/Dockerfile +23 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/app.py +123 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/init_db.py +46 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/models.py +36 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/requirements.txt +4 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/run.sh +21 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/css/style.css +368 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/js/admin.js +0 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/dashboard.html +21 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/edit_post.html +24 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/login.html +21 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/posts.html +53 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/base.html +45 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/index.html +29 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/post.html +14 -0
- veadk/integrations/ve_identity/__init__.py +110 -0
- veadk/integrations/ve_identity/auth_config.py +261 -0
- veadk/integrations/ve_identity/auth_mixins.py +650 -0
- veadk/integrations/ve_identity/auth_processor.py +385 -0
- veadk/integrations/ve_identity/function_tool.py +158 -0
- veadk/integrations/ve_identity/identity_client.py +864 -0
- veadk/integrations/ve_identity/mcp_tool.py +181 -0
- veadk/integrations/ve_identity/mcp_toolset.py +431 -0
- veadk/integrations/ve_identity/models.py +228 -0
- veadk/integrations/ve_identity/token_manager.py +188 -0
- veadk/integrations/ve_identity/utils.py +151 -0
- veadk/integrations/ve_prompt_pilot/__init__.py +13 -0
- veadk/integrations/ve_prompt_pilot/ve_prompt_pilot.py +85 -0
- veadk/integrations/ve_tls/__init__.py +13 -0
- veadk/integrations/ve_tls/utils.py +116 -0
- veadk/integrations/ve_tls/ve_tls.py +212 -0
- veadk/integrations/ve_tos/ve_tos.py +710 -0
- veadk/integrations/ve_viking_db_memory/__init__.py +13 -0
- veadk/integrations/ve_viking_db_memory/ve_viking_db_memory.py +308 -0
- veadk/knowledgebase/__init__.py +17 -0
- veadk/knowledgebase/backends/__init__.py +13 -0
- veadk/knowledgebase/backends/base_backend.py +72 -0
- veadk/knowledgebase/backends/in_memory_backend.py +91 -0
- veadk/knowledgebase/backends/opensearch_backend.py +162 -0
- veadk/knowledgebase/backends/redis_backend.py +172 -0
- veadk/knowledgebase/backends/utils.py +92 -0
- veadk/knowledgebase/backends/vikingdb_knowledge_backend.py +608 -0
- veadk/knowledgebase/entry.py +25 -0
- veadk/knowledgebase/knowledgebase.py +307 -0
- veadk/memory/__init__.py +35 -0
- veadk/memory/long_term_memory.py +365 -0
- veadk/memory/long_term_memory_backends/__init__.py +13 -0
- veadk/memory/long_term_memory_backends/base_backend.py +35 -0
- veadk/memory/long_term_memory_backends/in_memory_backend.py +67 -0
- veadk/memory/long_term_memory_backends/mem0_backend.py +155 -0
- veadk/memory/long_term_memory_backends/opensearch_backend.py +124 -0
- veadk/memory/long_term_memory_backends/redis_backend.py +140 -0
- veadk/memory/long_term_memory_backends/vikingdb_memory_backend.py +189 -0
- veadk/memory/short_term_memory.py +252 -0
- veadk/memory/short_term_memory_backends/__init__.py +13 -0
- veadk/memory/short_term_memory_backends/base_backend.py +31 -0
- veadk/memory/short_term_memory_backends/mysql_backend.py +49 -0
- veadk/memory/short_term_memory_backends/postgresql_backend.py +49 -0
- veadk/memory/short_term_memory_backends/sqlite_backend.py +55 -0
- veadk/memory/short_term_memory_processor.py +100 -0
- veadk/processors/__init__.py +26 -0
- veadk/processors/base_run_processor.py +120 -0
- veadk/prompts/__init__.py +13 -0
- veadk/prompts/agent_default_prompt.py +30 -0
- veadk/prompts/prompt_evaluator.py +20 -0
- veadk/prompts/prompt_memory_processor.py +55 -0
- veadk/prompts/prompt_optimization.py +150 -0
- veadk/runner.py +732 -0
- veadk/tools/__init__.py +13 -0
- veadk/tools/builtin_tools/__init__.py +13 -0
- veadk/tools/builtin_tools/agent_authorization.py +94 -0
- veadk/tools/builtin_tools/generate_image.py +23 -0
- veadk/tools/builtin_tools/image_edit.py +300 -0
- veadk/tools/builtin_tools/image_generate.py +446 -0
- veadk/tools/builtin_tools/lark.py +67 -0
- veadk/tools/builtin_tools/las.py +24 -0
- veadk/tools/builtin_tools/link_reader.py +66 -0
- veadk/tools/builtin_tools/llm_shield.py +381 -0
- veadk/tools/builtin_tools/load_knowledgebase.py +97 -0
- veadk/tools/builtin_tools/mcp_router.py +29 -0
- veadk/tools/builtin_tools/run_code.py +113 -0
- veadk/tools/builtin_tools/tts.py +253 -0
- veadk/tools/builtin_tools/vesearch.py +49 -0
- veadk/tools/builtin_tools/video_generate.py +363 -0
- veadk/tools/builtin_tools/web_scraper.py +76 -0
- veadk/tools/builtin_tools/web_search.py +83 -0
- veadk/tools/demo_tools.py +58 -0
- veadk/tools/load_knowledgebase_tool.py +149 -0
- veadk/tools/sandbox/__init__.py +13 -0
- veadk/tools/sandbox/browser_sandbox.py +37 -0
- veadk/tools/sandbox/code_sandbox.py +40 -0
- veadk/tools/sandbox/computer_sandbox.py +34 -0
- veadk/tracing/__init__.py +13 -0
- veadk/tracing/base_tracer.py +58 -0
- veadk/tracing/telemetry/__init__.py +13 -0
- veadk/tracing/telemetry/attributes/attributes.py +29 -0
- veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +180 -0
- veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +858 -0
- veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py +152 -0
- veadk/tracing/telemetry/attributes/extractors/types.py +164 -0
- veadk/tracing/telemetry/exporters/__init__.py +13 -0
- veadk/tracing/telemetry/exporters/apmplus_exporter.py +558 -0
- veadk/tracing/telemetry/exporters/base_exporter.py +39 -0
- veadk/tracing/telemetry/exporters/cozeloop_exporter.py +129 -0
- veadk/tracing/telemetry/exporters/inmemory_exporter.py +248 -0
- veadk/tracing/telemetry/exporters/tls_exporter.py +139 -0
- veadk/tracing/telemetry/opentelemetry_tracer.py +320 -0
- veadk/tracing/telemetry/telemetry.py +411 -0
- veadk/types.py +47 -0
- veadk/utils/__init__.py +13 -0
- veadk/utils/audio_manager.py +95 -0
- veadk/utils/auth.py +294 -0
- veadk/utils/logger.py +59 -0
- veadk/utils/mcp_utils.py +44 -0
- veadk/utils/misc.py +184 -0
- veadk/utils/patches.py +101 -0
- veadk/utils/volcengine_sign.py +205 -0
- veadk/version.py +15 -0
- veadk_python-0.2.27.dist-info/METADATA +373 -0
- veadk_python-0.2.27.dist-info/RECORD +218 -0
- veadk_python-0.2.27.dist-info/WHEEL +5 -0
- veadk_python-0.2.27.dist-info/entry_points.txt +2 -0
- veadk_python-0.2.27.dist-info/licenses/LICENSE +201 -0
- veadk_python-0.2.27.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,220 @@
|
|
|
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 time
|
|
16
|
+
|
|
17
|
+
from veadk.consts import (
|
|
18
|
+
DEFAULT_CR_INSTANCE_NAME,
|
|
19
|
+
DEFAULT_CR_NAMESPACE_NAME,
|
|
20
|
+
DEFAULT_CR_REPO_NAME,
|
|
21
|
+
)
|
|
22
|
+
from veadk.utils.logger import get_logger
|
|
23
|
+
from veadk.utils.volcengine_sign import ve_request
|
|
24
|
+
|
|
25
|
+
logger = get_logger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class VeCR:
|
|
29
|
+
def __init__(self, access_key: str, secret_key: str, region: str = "cn-beijing"):
|
|
30
|
+
self.ak = access_key
|
|
31
|
+
self.sk = secret_key
|
|
32
|
+
self.region = region
|
|
33
|
+
assert region in ["cn-beijing", "cn-guangzhou", "cn-shanghai"]
|
|
34
|
+
self.version = "2022-05-12"
|
|
35
|
+
|
|
36
|
+
def _create_instance(self, instance_name: str = DEFAULT_CR_INSTANCE_NAME) -> str:
|
|
37
|
+
"""
|
|
38
|
+
create cr instance
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
instance_name: cr instance name
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
cr instance name
|
|
45
|
+
"""
|
|
46
|
+
status = self._check_instance(instance_name)
|
|
47
|
+
if status != "NONEXIST":
|
|
48
|
+
logger.debug(f"cr instance {instance_name} already running")
|
|
49
|
+
return instance_name
|
|
50
|
+
response = ve_request(
|
|
51
|
+
request_body={
|
|
52
|
+
"Name": instance_name,
|
|
53
|
+
"ResourceTags": [
|
|
54
|
+
{"Key": "provider", "Value": "veadk"},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
action="CreateRegistry",
|
|
58
|
+
ak=self.ak,
|
|
59
|
+
sk=self.sk,
|
|
60
|
+
service="cr",
|
|
61
|
+
version=self.version,
|
|
62
|
+
region=self.region,
|
|
63
|
+
host=f"cr.{self.region}.volcengineapi.com",
|
|
64
|
+
)
|
|
65
|
+
logger.debug(f"create cr instance {instance_name}: {response}")
|
|
66
|
+
|
|
67
|
+
if "Error" in response["ResponseMetadata"]:
|
|
68
|
+
error_code = response["ResponseMetadata"]["Error"]["Code"]
|
|
69
|
+
error_message = response["ResponseMetadata"]["Error"]["Message"]
|
|
70
|
+
if error_code == "AlreadyExists.Registry":
|
|
71
|
+
logger.debug(f"cr instance {instance_name} already exists")
|
|
72
|
+
return instance_name
|
|
73
|
+
else:
|
|
74
|
+
logger.error(
|
|
75
|
+
f"Error create cr instance {instance_name}: {error_code} {error_message}"
|
|
76
|
+
)
|
|
77
|
+
raise ValueError(
|
|
78
|
+
f"Error create cr instance {instance_name}: {error_code} {error_message}"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
while True:
|
|
82
|
+
status = self._check_instance(instance_name)
|
|
83
|
+
if status == "Running":
|
|
84
|
+
break
|
|
85
|
+
elif status == "Failed":
|
|
86
|
+
raise ValueError(f"cr instance {instance_name} create failed")
|
|
87
|
+
else:
|
|
88
|
+
logger.debug(f"cr instance status: {status}")
|
|
89
|
+
time.sleep(30)
|
|
90
|
+
|
|
91
|
+
return instance_name
|
|
92
|
+
|
|
93
|
+
def _check_instance(self, instance_name: str) -> str:
|
|
94
|
+
"""
|
|
95
|
+
check cr instance status
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
instance_name: cr instance name
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
cr instance status
|
|
102
|
+
"""
|
|
103
|
+
response = ve_request(
|
|
104
|
+
request_body={
|
|
105
|
+
"Filter": {
|
|
106
|
+
"Names": [instance_name],
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
action="ListRegistries",
|
|
110
|
+
ak=self.ak,
|
|
111
|
+
sk=self.sk,
|
|
112
|
+
service="cr",
|
|
113
|
+
version=self.version,
|
|
114
|
+
region=self.region,
|
|
115
|
+
host=f"cr.{self.region}.volcengineapi.com",
|
|
116
|
+
)
|
|
117
|
+
logger.debug(f"check cr instance {instance_name}: {response}")
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
if response["Result"]["TotalCount"] == 0:
|
|
121
|
+
return "NONEXIST"
|
|
122
|
+
return response["Result"]["Items"][0]["Status"]["Phase"]
|
|
123
|
+
except Exception as _:
|
|
124
|
+
raise ValueError(f"Error check cr instance {instance_name}: {response}")
|
|
125
|
+
|
|
126
|
+
def _create_namespace(
|
|
127
|
+
self,
|
|
128
|
+
instance_name: str = DEFAULT_CR_INSTANCE_NAME,
|
|
129
|
+
namespace_name: str = DEFAULT_CR_NAMESPACE_NAME,
|
|
130
|
+
) -> str:
|
|
131
|
+
"""
|
|
132
|
+
create cr namespace
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
instance_name: cr instance name
|
|
136
|
+
namespace_name: cr namespace name
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
cr namespace name
|
|
140
|
+
"""
|
|
141
|
+
response = ve_request(
|
|
142
|
+
request_body={
|
|
143
|
+
"Name": namespace_name,
|
|
144
|
+
"Registry": instance_name,
|
|
145
|
+
},
|
|
146
|
+
action="CreateNamespace",
|
|
147
|
+
ak=self.ak,
|
|
148
|
+
sk=self.sk,
|
|
149
|
+
service="cr",
|
|
150
|
+
version=self.version,
|
|
151
|
+
region=self.region,
|
|
152
|
+
host=f"cr.{self.region}.volcengineapi.com",
|
|
153
|
+
)
|
|
154
|
+
logger.debug(f"create cr namespace {namespace_name}: {response}")
|
|
155
|
+
|
|
156
|
+
if "Error" in response["ResponseMetadata"]:
|
|
157
|
+
error_code = response["ResponseMetadata"]["Error"]["Code"]
|
|
158
|
+
error_message = response["ResponseMetadata"]["Error"]["Message"]
|
|
159
|
+
if error_code == "AlreadyExists.Namespace":
|
|
160
|
+
logger.warning(f"cr namespace {namespace_name} already exists")
|
|
161
|
+
return namespace_name
|
|
162
|
+
else:
|
|
163
|
+
logger.error(
|
|
164
|
+
f"Error create cr namespace {namespace_name}: {error_code} {error_message}"
|
|
165
|
+
)
|
|
166
|
+
raise ValueError(
|
|
167
|
+
f"Error create cr namespace {namespace_name}: {error_code} {error_message}"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
return namespace_name
|
|
171
|
+
|
|
172
|
+
def _create_repo(
|
|
173
|
+
self,
|
|
174
|
+
instance_name: str = DEFAULT_CR_INSTANCE_NAME,
|
|
175
|
+
namespace_name: str = DEFAULT_CR_NAMESPACE_NAME,
|
|
176
|
+
repo_name: str = DEFAULT_CR_REPO_NAME,
|
|
177
|
+
) -> str:
|
|
178
|
+
"""
|
|
179
|
+
create cr repo
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
instance_name: cr instance name
|
|
183
|
+
namespace_name: cr namespace name
|
|
184
|
+
repo_name: cr repo name
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
cr repo name
|
|
188
|
+
"""
|
|
189
|
+
response = ve_request(
|
|
190
|
+
request_body={
|
|
191
|
+
"Name": repo_name,
|
|
192
|
+
"Registry": instance_name,
|
|
193
|
+
"Namespace": namespace_name,
|
|
194
|
+
"Description": "veadk cr repo",
|
|
195
|
+
},
|
|
196
|
+
action="CreateRepository",
|
|
197
|
+
ak=self.ak,
|
|
198
|
+
sk=self.sk,
|
|
199
|
+
service="cr",
|
|
200
|
+
version=self.version,
|
|
201
|
+
region=self.region,
|
|
202
|
+
host=f"cr.{self.region}.volcengineapi.com",
|
|
203
|
+
)
|
|
204
|
+
logger.debug(f"create cr repo {repo_name}: {response}")
|
|
205
|
+
|
|
206
|
+
if "Error" in response["ResponseMetadata"]:
|
|
207
|
+
error_code = response["ResponseMetadata"]["Error"]["Code"]
|
|
208
|
+
error_message = response["ResponseMetadata"]["Error"]["Message"]
|
|
209
|
+
if error_code == "AlreadyExists.Repository":
|
|
210
|
+
logger.debug(f"cr repo {repo_name} already exists")
|
|
211
|
+
return repo_name
|
|
212
|
+
else:
|
|
213
|
+
logger.error(
|
|
214
|
+
f"Error create cr repo {repo_name}: {error_code} {error_message}"
|
|
215
|
+
)
|
|
216
|
+
raise ValueError(
|
|
217
|
+
f"Error create cr repo {repo_name}: {error_code} {error_message}"
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
return repo_name
|
|
@@ -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,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"local_dir_name": "veadk_vefaas_proj",
|
|
3
|
+
"app_name": "weather_report",
|
|
4
|
+
"agent_module_name": "weather_agent",
|
|
5
|
+
"short_term_memory_backend": "local",
|
|
6
|
+
"vefaas_application_name": "weather-reporter",
|
|
7
|
+
"veapig_instance_name": "",
|
|
8
|
+
"veapig_service_name": "",
|
|
9
|
+
"veapig_upstream_name": "",
|
|
10
|
+
"use_adk_web": false,
|
|
11
|
+
"auth_method": "none",
|
|
12
|
+
"veidentity_user_pool_name": "",
|
|
13
|
+
"veidentity_client_name": "",
|
|
14
|
+
"veadk_version": ""
|
|
15
|
+
}
|
|
@@ -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,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
|
+
from veadk.cloud.cloud_app import CloudApp
|
|
16
|
+
|
|
17
|
+
def main() -> None:
|
|
18
|
+
cloud_app = CloudApp(vefaas_application_name="{{cookiecutter.vefaas_application_name}}")
|
|
19
|
+
cloud_app.delete_self()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if __name__ == "__main__":
|
|
23
|
+
main()
|
|
@@ -0,0 +1,106 @@
|
|
|
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 asyncio
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
from a2a.types import TextPart
|
|
19
|
+
from fastmcp.client import Client
|
|
20
|
+
|
|
21
|
+
from veadk.cloud.cloud_agent_engine import CloudAgentEngine
|
|
22
|
+
from veadk.cloud.cloud_app import CloudApp, get_message_id
|
|
23
|
+
|
|
24
|
+
SESSION_ID = "cloud_app_test_session"
|
|
25
|
+
USER_ID = "cloud_app_test_user"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
async def _send_msg_with_a2a(cloud_app: CloudApp, message: str) -> None:
|
|
29
|
+
print("===== A2A example =====")
|
|
30
|
+
|
|
31
|
+
response_message = await cloud_app.message_send(message, SESSION_ID, USER_ID)
|
|
32
|
+
|
|
33
|
+
if not response_message or not response_message.parts:
|
|
34
|
+
print(
|
|
35
|
+
"No response from VeFaaS application. Something wrong with cloud application."
|
|
36
|
+
)
|
|
37
|
+
return
|
|
38
|
+
|
|
39
|
+
print(f"Message ID: {get_message_id(response_message)}")
|
|
40
|
+
|
|
41
|
+
if isinstance(response_message.parts[0].root, TextPart):
|
|
42
|
+
print(
|
|
43
|
+
f"Response from {cloud_app.vefaas_endpoint}: {response_message.parts[0].root.text}"
|
|
44
|
+
)
|
|
45
|
+
else:
|
|
46
|
+
print(
|
|
47
|
+
f"Response from {cloud_app.vefaas_endpoint}: {response_message.parts[0].root}"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
async def _send_msg_with_mcp(cloud_app: CloudApp, message: str) -> None:
|
|
52
|
+
print("===== MCP example =====")
|
|
53
|
+
|
|
54
|
+
endpoint = cloud_app._get_vefaas_endpoint()
|
|
55
|
+
print(f"MCP server endpoint: {endpoint}/mcp")
|
|
56
|
+
|
|
57
|
+
# Connect to MCP server
|
|
58
|
+
client = Client(f"{endpoint}/mcp")
|
|
59
|
+
|
|
60
|
+
async with client:
|
|
61
|
+
# List available tools
|
|
62
|
+
tools = await client.list_tools()
|
|
63
|
+
print(f"Available tools: {tools}")
|
|
64
|
+
|
|
65
|
+
# Call run_agent tool, pass user input and session information
|
|
66
|
+
res = await client.call_tool(
|
|
67
|
+
"run_agent",
|
|
68
|
+
{
|
|
69
|
+
"user_input": message,
|
|
70
|
+
"session_id": SESSION_ID,
|
|
71
|
+
"user_id": USER_ID,
|
|
72
|
+
},
|
|
73
|
+
)
|
|
74
|
+
print(f"Response from {cloud_app.vefaas_endpoint}: {res}")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async def main():
|
|
78
|
+
engine = CloudAgentEngine()
|
|
79
|
+
|
|
80
|
+
cloud_app = engine.deploy(
|
|
81
|
+
path=str(Path(__file__).parent / "src"),
|
|
82
|
+
application_name="{{cookiecutter.vefaas_application_name}}",
|
|
83
|
+
gateway_name="{{cookiecutter.veapig_instance_name}}",
|
|
84
|
+
gateway_service_name="{{cookiecutter.veapig_service_name}}",
|
|
85
|
+
gateway_upstream_name="{{cookiecutter.veapig_upstream_name}}",
|
|
86
|
+
use_adk_web={{cookiecutter.use_adk_web}},
|
|
87
|
+
auth_method="{{cookiecutter.auth_method}}",
|
|
88
|
+
identity_user_pool_name="{{cookiecutter.veidentity_user_pool_name}}",
|
|
89
|
+
identity_client_name="{{cookiecutter.veidentity_client_name}}",
|
|
90
|
+
local_test=False, # Set to True for local testing before deploy to VeFaaS
|
|
91
|
+
)
|
|
92
|
+
print(f"VeFaaS application ID: {cloud_app.vefaas_application_id}")
|
|
93
|
+
|
|
94
|
+
if {{cookiecutter.use_adk_web}}:
|
|
95
|
+
print(f"Web is running at: {cloud_app.vefaas_endpoint}")
|
|
96
|
+
else:
|
|
97
|
+
# Test with deployed cloud application
|
|
98
|
+
message = "How is the weather like in Beijing?"
|
|
99
|
+
print(f"Test message: {message}")
|
|
100
|
+
|
|
101
|
+
# await _send_msg_with_a2a(cloud_app=cloud_app, message=message)
|
|
102
|
+
# await _send_msg_with_mcp(cloud_app=cloud_app, message=message)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
if __name__ == "__main__":
|
|
106
|
+
asyncio.run(main())
|
|
@@ -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,25 @@
|
|
|
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 {{ cookiecutter.app_name }}.agent import agent # type: ignore
|
|
16
|
+
|
|
17
|
+
from veadk.memory.short_term_memory import ShortTermMemory
|
|
18
|
+
from veadk.types import AgentRunConfig
|
|
19
|
+
|
|
20
|
+
# [required] instantiate the agent run configuration
|
|
21
|
+
agent_run_config = AgentRunConfig(
|
|
22
|
+
app_name="{{ cookiecutter.app_name }}",
|
|
23
|
+
agent=agent, # type: ignore
|
|
24
|
+
short_term_memory=ShortTermMemory(backend="{{ cookiecutter.short_term_memory_backend }}"), # type: ignore
|
|
25
|
+
)
|
|
@@ -0,0 +1,202 @@
|
|
|
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 os
|
|
16
|
+
from contextlib import asynccontextmanager
|
|
17
|
+
from typing import Callable
|
|
18
|
+
|
|
19
|
+
from agent import agent_run_config
|
|
20
|
+
|
|
21
|
+
from fastapi import FastAPI
|
|
22
|
+
from fastapi.routing import APIRoute
|
|
23
|
+
|
|
24
|
+
from fastmcp import FastMCP
|
|
25
|
+
|
|
26
|
+
from starlette.routing import Route
|
|
27
|
+
|
|
28
|
+
from google.adk.a2a.utils.agent_card_builder import AgentCardBuilder
|
|
29
|
+
from a2a.types import AgentProvider
|
|
30
|
+
|
|
31
|
+
from veadk.a2a.ve_a2a_server import init_app
|
|
32
|
+
from veadk.runner import Runner
|
|
33
|
+
from veadk.tracing.telemetry.exporters.apmplus_exporter import APMPlusExporter
|
|
34
|
+
from veadk.tracing.telemetry.exporters.cozeloop_exporter import CozeloopExporter
|
|
35
|
+
from veadk.tracing.telemetry.exporters.tls_exporter import TLSExporter
|
|
36
|
+
from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer
|
|
37
|
+
from veadk.types import AgentRunConfig
|
|
38
|
+
from veadk.utils.logger import get_logger
|
|
39
|
+
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
|
|
40
|
+
from opentelemetry import context
|
|
41
|
+
|
|
42
|
+
logger = get_logger(__name__)
|
|
43
|
+
|
|
44
|
+
assert isinstance(agent_run_config, AgentRunConfig), (
|
|
45
|
+
f"Invalid agent_run_config type: {type(agent_run_config)}, expected `AgentRunConfig`"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
app_name = agent_run_config.app_name
|
|
49
|
+
agent = agent_run_config.agent
|
|
50
|
+
short_term_memory = agent_run_config.short_term_memory
|
|
51
|
+
|
|
52
|
+
VEFAAS_REGION = os.getenv("APP_REGION", "cn-beijing")
|
|
53
|
+
VEFAAS_FUNC_ID = os.getenv("_FAAS_FUNC_ID", "")
|
|
54
|
+
agent_card_builder = AgentCardBuilder(agent=agent, provider=AgentProvider(organization="Volcengine Agent Development Kit (VeADK)", url=f"https://console.volcengine.com/vefaas/region:vefaas+{VEFAAS_REGION}/function/detail/{VEFAAS_FUNC_ID}"))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def load_tracer() -> None:
|
|
58
|
+
EXPORTER_REGISTRY = {
|
|
59
|
+
"VEADK_TRACER_APMPLUS": APMPlusExporter,
|
|
60
|
+
"VEADK_TRACER_COZELOOP": CozeloopExporter,
|
|
61
|
+
"VEADK_TRACER_TLS": TLSExporter,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
exporters = []
|
|
65
|
+
for env_var, exporter_cls in EXPORTER_REGISTRY.items():
|
|
66
|
+
if os.getenv(env_var, "").lower() == "true":
|
|
67
|
+
if (
|
|
68
|
+
agent.tracers
|
|
69
|
+
and isinstance(agent.tracers[0], OpentelemetryTracer)
|
|
70
|
+
and any(isinstance(e, exporter_cls) for e in agent.tracers[0].exporters)
|
|
71
|
+
):
|
|
72
|
+
logger.warning(
|
|
73
|
+
f"Exporter {exporter_cls.__name__} is already defined in agent.tracers[0].exporters. These two exporters will be used at the same time. As a result, your data may be uploaded twice."
|
|
74
|
+
)
|
|
75
|
+
else:
|
|
76
|
+
exporters.append(exporter_cls())
|
|
77
|
+
|
|
78
|
+
tracer = OpentelemetryTracer(name="veadk_tracer", exporters=exporters)
|
|
79
|
+
agent_run_config.agent.tracers.extend([tracer])
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def build_mcp_run_agent_func() -> Callable:
|
|
83
|
+
runner = Runner(
|
|
84
|
+
agent=agent,
|
|
85
|
+
short_term_memory=short_term_memory,
|
|
86
|
+
app_name=app_name,
|
|
87
|
+
user_id="",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
async def run_agent(
|
|
91
|
+
user_input: str,
|
|
92
|
+
user_id: str = "mcp_user",
|
|
93
|
+
session_id: str = "mcp_session",
|
|
94
|
+
) -> str:
|
|
95
|
+
# Set user_id for runner
|
|
96
|
+
runner.user_id = user_id
|
|
97
|
+
|
|
98
|
+
# Running agent and get final output
|
|
99
|
+
final_output = await runner.run(
|
|
100
|
+
messages=user_input,
|
|
101
|
+
session_id=session_id,
|
|
102
|
+
)
|
|
103
|
+
return final_output
|
|
104
|
+
|
|
105
|
+
run_agent_doc = f"""{agent.description}
|
|
106
|
+
Args:
|
|
107
|
+
user_input: User's input message (required).
|
|
108
|
+
user_id: User identifier. Defaults to "mcp_user".
|
|
109
|
+
session_id: Session identifier. Defaults to "mcp_session".
|
|
110
|
+
Returns:
|
|
111
|
+
Final agent response as a string."""
|
|
112
|
+
|
|
113
|
+
run_agent.__doc__ = run_agent_doc
|
|
114
|
+
|
|
115
|
+
return run_agent
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
async def agent_card() -> dict:
|
|
119
|
+
agent_card = await agent_card_builder.build()
|
|
120
|
+
return agent_card.model_dump()
|
|
121
|
+
|
|
122
|
+
async def get_cozeloop_space_id() -> dict:
|
|
123
|
+
return {"space_id": os.getenv("OBSERVABILITY_OPENTELEMETRY_COZELOOP_SERVICE_NAME", default="")}
|
|
124
|
+
|
|
125
|
+
load_tracer()
|
|
126
|
+
|
|
127
|
+
# Build a run_agent function for building MCP server
|
|
128
|
+
run_agent_func = build_mcp_run_agent_func()
|
|
129
|
+
|
|
130
|
+
a2a_app = init_app(
|
|
131
|
+
server_url="0.0.0.0",
|
|
132
|
+
app_name=app_name,
|
|
133
|
+
agent=agent,
|
|
134
|
+
short_term_memory=short_term_memory,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
a2a_app.post("/run_agent", operation_id="run_agent", tags=["mcp"])(run_agent_func)
|
|
138
|
+
a2a_app.get("/agent_card", operation_id="agent_card", tags=["mcp"])(agent_card)
|
|
139
|
+
a2a_app.get("/get_cozeloop_space_id", operation_id="get_cozeloop_space_id", tags=["mcp"])(get_cozeloop_space_id)
|
|
140
|
+
|
|
141
|
+
# === Build mcp server ===
|
|
142
|
+
|
|
143
|
+
mcp = FastMCP.from_fastapi(app=a2a_app, name=app_name, include_tags={"mcp"})
|
|
144
|
+
|
|
145
|
+
# Create MCP ASGI app
|
|
146
|
+
mcp_app = mcp.http_app(path="/", transport="streamable-http")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# Combined lifespan management
|
|
150
|
+
@asynccontextmanager
|
|
151
|
+
async def combined_lifespan(app: FastAPI):
|
|
152
|
+
async with mcp_app.lifespan(app):
|
|
153
|
+
yield
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
# Create main FastAPI app with combined lifespan
|
|
157
|
+
app = FastAPI(
|
|
158
|
+
title=a2a_app.title,
|
|
159
|
+
version=a2a_app.version,
|
|
160
|
+
lifespan=combined_lifespan,
|
|
161
|
+
openapi_url=None,
|
|
162
|
+
docs_url=None,
|
|
163
|
+
redoc_url=None
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
@app.middleware("http")
|
|
167
|
+
async def otel_context_middleware(request, call_next):
|
|
168
|
+
carrier = {
|
|
169
|
+
"traceparent": request.headers.get("Traceparent"),
|
|
170
|
+
"tracestate": request.headers.get("Tracestate"),
|
|
171
|
+
}
|
|
172
|
+
logger.debug(f"carrier: {carrier}")
|
|
173
|
+
if carrier["traceparent"] is None:
|
|
174
|
+
return await call_next(request)
|
|
175
|
+
else:
|
|
176
|
+
ctx = TraceContextTextMapPropagator().extract(carrier=carrier)
|
|
177
|
+
logger.debug(f"ctx: {ctx}")
|
|
178
|
+
token = context.attach(ctx)
|
|
179
|
+
try:
|
|
180
|
+
response = await call_next(request)
|
|
181
|
+
finally:
|
|
182
|
+
context.detach(token)
|
|
183
|
+
return response
|
|
184
|
+
|
|
185
|
+
# Mount A2A routes to main app
|
|
186
|
+
for route in a2a_app.routes:
|
|
187
|
+
app.routes.append(route)
|
|
188
|
+
|
|
189
|
+
# Mount MCP server at /mcp endpoint
|
|
190
|
+
app.mount("/mcp", mcp_app)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
# remove openapi routes
|
|
194
|
+
paths = ["/openapi.json", "/docs", "/redoc"]
|
|
195
|
+
new_routes = []
|
|
196
|
+
for route in app.router.routes:
|
|
197
|
+
if isinstance(route, (APIRoute, Route)) and route.path in paths:
|
|
198
|
+
continue
|
|
199
|
+
new_routes.append(route)
|
|
200
|
+
app.router.routes = new_routes
|
|
201
|
+
|
|
202
|
+
# === Build mcp server end ===
|