Skip to content

Commit ff3f697

Browse files
author
wangjiaju.716
committed
Merge branch 'main' of https://github.com/doraemonlove/veadk-python into fix/builtintooltrace
2 parents 98c7252 + f274d6c commit ff3f697

File tree

10 files changed

+112
-32
lines changed

10 files changed

+112
-32
lines changed

tests/test_cloud.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,12 @@ async def test_cloud():
115115
mock_vefaas_client = Mock()
116116
mock_vefaas_in_app.return_value = mock_vefaas_client
117117
mock_vefaas_client.delete.return_value = None
118-
119-
cloud_app.delete_self()
120-
mock_vefaas_client.delete.assert_called_with("app-123")
118+
with patch.object(
119+
cloud_app, "_get_vefaas_application_id_by_name"
120+
) as mock_get_id_by_name:
121+
mock_get_id_by_name.return_value = None
122+
cloud_app.delete_self()
123+
mock_vefaas_client.delete.assert_called_with("app-123")
121124

122125
# Verify all mocks were called as expected
123126
mock_vefaas_service.deploy.assert_called_once()

veadk/agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
from veadk.config import getenv
3030
from veadk.consts import (
31-
DEFALUT_MODEL_AGENT_PROVIDER,
31+
DEFAULT_MODEL_AGENT_PROVIDER,
3232
DEFAULT_MODEL_AGENT_API_BASE,
3333
DEFAULT_MODEL_AGENT_NAME,
3434
DEFAULT_MODEL_EXTRA_HEADERS,
@@ -65,7 +65,7 @@ class Agent(LlmAgent):
6565
model_name: str = getenv("MODEL_AGENT_NAME", DEFAULT_MODEL_AGENT_NAME)
6666
"""The name of the model for agent running."""
6767

68-
model_provider: str = getenv("MODEL_AGENT_PROVIDER", DEFALUT_MODEL_AGENT_PROVIDER)
68+
model_provider: str = getenv("MODEL_AGENT_PROVIDER", DEFAULT_MODEL_AGENT_PROVIDER)
6969
"""The provider of the model for agent running."""
7070

7171
model_api_base: str = getenv("MODEL_AGENT_API_BASE", DEFAULT_MODEL_AGENT_API_BASE)

veadk/cloud/cloud_app.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import json
16+
import time
1617
from typing import Any
1718
from uuid import uuid4
1819

@@ -60,9 +61,11 @@ def __init__(
6061
if not vefaas_endpoint:
6162
self.vefaas_endpoint = self._get_vefaas_endpoint()
6263

63-
if not self.vefaas_endpoint.startswith(
64-
"http"
65-
) and not self.vefaas_endpoint.startswith("https"):
64+
if (
65+
self.vefaas_endpoint
66+
and not self.vefaas_endpoint.startswith("http")
67+
and not self.vefaas_endpoint.startswith("https")
68+
):
6669
raise ValueError(
6770
f"Invalid endpoint: {vefaas_endpoint}. The endpoint must start with `http` or `https`."
6871
)
@@ -92,12 +95,13 @@ def _get_vefaas_endpoint(
9295
raise ValueError(
9396
f"VeFaaS CloudAPP with application_id `{self.vefaas_application_id}` or application_name `{self.vefaas_application_name}` not found."
9497
)
95-
cloud_resource = json.loads(app["CloudResource"])
9698

9799
try:
100+
cloud_resource = json.loads(app["CloudResource"])
98101
vefaas_endpoint = cloud_resource["framework"]["url"]["system_url"]
99102
except Exception as e:
100-
raise ValueError(f"VeFaaS cloudAPP could not get endpoint. Error: {e}")
103+
logger.warning(f"VeFaaS cloudAPP could not get endpoint. Error: {e}")
104+
vefaas_endpoint = ""
101105
return vefaas_endpoint
102106

103107
def _get_vefaas_application_id_by_name(self) -> str:
@@ -167,7 +171,18 @@ def delete_self(
167171

168172
vefaas_client = VeFaaS(access_key=volcengine_ak, secret_key=volcengine_sk)
169173
vefaas_client.delete(self.vefaas_application_id)
170-
print(f"Cloud app {self.vefaas_application_id} is deleting...")
174+
print(
175+
f"Cloud app {self.vefaas_application_id} delete request has been sent to VeFaaS"
176+
)
177+
while True:
178+
try:
179+
id = self._get_vefaas_application_id_by_name()
180+
if not id:
181+
break
182+
time.sleep(3)
183+
except Exception as _:
184+
break
185+
print("Delete application done.")
171186

172187
async def message_send(
173188
self, message: str, session_id: str, user_id: str, timeout: float = 600.0

veadk/consts.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@
1515
from veadk.version import VERSION
1616

1717
DEFAULT_MODEL_AGENT_NAME = "doubao-seed-1-6-250615"
18-
DEFALUT_MODEL_AGENT_PROVIDER = "openai"
18+
DEFAULT_MODEL_AGENT_PROVIDER = "openai"
1919
DEFAULT_MODEL_AGENT_API_BASE = "https://ark.cn-beijing.volces.com/api/v3/"
2020
DEFAULT_MODEL_EXTRA_HEADERS = {"veadk-source": "veadk", "veadk-version": VERSION}
21+
22+
DEFAULT_APMPLUS_OTEL_EXPORTER_ENDPOINT = "http://apmplus-cn-beijing.volces.com:4317"
23+
DEFAULT_APMPLUS_OTEL_EXPORTER_SERVICE_NAME = "veadk_tracing"
24+
25+
DEFAULT_COZELOOP_OTEL_EXPORTER_ENDPOINT = (
26+
"https://api.coze.cn/v1/loop/opentelemetry/v1/traces"
27+
)
28+
29+
DEFAULT_TLS_OTEL_EXPORTER_ENDPOINT = "https://tls-cn-beijing.volces.com:4318/v1/traces"
30+
DEFAULT_TLS_OTEL_EXPORTER_REGION = "cn-beijing"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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()

veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from starlette.routing import Route
2727

2828
from google.adk.a2a.utils.agent_card_builder import AgentCardBuilder
29+
from a2a.types import AgentProvider
2930

3031
from veadk.a2a.ve_a2a_server import init_app
3132
from veadk.runner import Runner
@@ -46,7 +47,9 @@
4647
agent = agent_run_config.agent
4748
short_term_memory = agent_run_config.short_term_memory
4849

49-
agent_card_builder = AgentCardBuilder(agent=agent)
50+
VEFAAS_REGION = os.getenv("APP_REGION", "cn-beijing")
51+
VEFAAS_FUNC_ID = os.getenv("_FAAS_FUNC_ID", "")
52+
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}"))
5053

5154

5255
def load_tracer() -> None:

veadk/tools/sandbox/computer_sandbox.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,23 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
computer_sandbox = ...
15+
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
1616

17+
from veadk.config import getenv
18+
from veadk.utils.mcp_utils import get_mcp_params
1719

18-
def computer_use(prompt: str) -> str:
19-
"""Using the remote computer sandbox to according to the prompt.
20+
url = getenv("TOOL_COMPUTER_SANDBOX_URL")
2021

21-
Args:
22-
prompt (str): The prompt to be used.
2322

24-
Returns:
25-
str: The response from the sandbox.
26-
"""
27-
...
23+
computer_sandbox = MCPToolset(connection_params=get_mcp_params(url=url))
24+
25+
# def computer_use(prompt: str) -> str:
26+
# """Using the remote computer sandbox to according to the prompt.
27+
28+
# Args:
29+
# prompt (str): The prompt to be used.
30+
31+
# Returns:
32+
# str: The response from the sandbox.
33+
# """
34+
# ...

veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
ExtractorResponse,
1919
LLMAttributesParams,
2020
)
21+
from veadk.utils.misc import safe_json_serialize
2122

2223

2324
def llm_gen_ai_request_model(params: LLMAttributesParams) -> ExtractorResponse:
@@ -133,7 +134,7 @@ def llm_gen_ai_prompt(params: LLMAttributesParams) -> ExtractorResponse:
133134
else "<unknown_function_name>"
134135
)
135136
message[f"gen_ai.prompt.{idx}.tool_calls.0.function.arguments"] = (
136-
json.dumps(part.function_call.args)
137+
safe_json_serialize(part.function_call.args)
137138
if part.function_call.args
138139
else json.dumps({})
139140
)
@@ -168,7 +169,7 @@ def llm_gen_ai_completion(params: LLMAttributesParams) -> ExtractorResponse:
168169
else "<unknown_function_name>"
169170
)
170171
message[f"gen_ai.completion.{idx}.tool_calls.0.function.arguments"] = (
171-
json.dumps(part.function_call.args)
172+
safe_json_serialize(part.function_call.args)
172173
if part.function_call.args
173174
else json.dumps({})
174175
)
@@ -289,7 +290,7 @@ def llm_gen_ai_assistant_message(params: LLMAttributesParams) -> ExtractorRespon
289290
else "<unknown_function_name>"
290291
)
291292
message_part["tool_calls.0.function.arguments"] = (
292-
json.dumps(part.function_call.args)
293+
safe_json_serialize(part.function_call.args)
293294
if part.function_call.args
294295
else json.dumps({})
295296
)
@@ -326,7 +327,7 @@ def llm_gen_ai_choice(params: LLMAttributesParams) -> ExtractorResponse:
326327
else "<unknown_function_name>"
327328
)
328329
message["message.tool_calls.0.function.arguments"] = (
329-
json.dumps(part.function_call.args)
330+
safe_json_serialize(part.function_call.args)
330331
if part.function_call.args
331332
else json.dumps({})
332333
)
@@ -351,7 +352,7 @@ def llm_gen_ai_choice(params: LLMAttributesParams) -> ExtractorResponse:
351352
else "<unknown_function_name>"
352353
)
353354
message["message.tool_calls.0.function.arguments"] = (
354-
json.dumps(part.function_call.args)
355+
safe_json_serialize(part.function_call.args)
355356
if part.function_call.args
356357
else json.dumps({})
357358
)

veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import json
16-
1715
from veadk.tracing.telemetry.attributes.extractors.types import (
1816
ExtractorResponse,
1917
ToolAttributesParams,
2018
)
19+
from veadk.utils.misc import safe_json_serialize
2120

2221

2322
def tool_gen_ai_operation_name(params: ToolAttributesParams) -> ExtractorResponse:
@@ -27,7 +26,7 @@ def tool_gen_ai_operation_name(params: ToolAttributesParams) -> ExtractorRespons
2726
def tool_gen_ai_tool_message(params: ToolAttributesParams) -> ExtractorResponse:
2827
tool_input = {
2928
"role": "tool",
30-
"content": json.dumps(
29+
"content": safe_json_serialize(
3130
{
3231
"name": params.tool.name,
3332
"description": params.tool.description,
@@ -45,7 +44,7 @@ def tool_gen_ai_tool_input(params: ToolAttributesParams) -> ExtractorResponse:
4544
"parameters": params.args,
4645
}
4746
return ExtractorResponse(
48-
content=json.dumps(tool_input, ensure_ascii=False) or "<unknown_tool_input>"
47+
content=safe_json_serialize(tool_input) or "<unknown_tool_input>"
4948
)
5049

5150

@@ -63,7 +62,7 @@ def tool_gen_ai_tool_output(params: ToolAttributesParams) -> ExtractorResponse:
6362
"response": function_response["response"],
6463
}
6564
return ExtractorResponse(
66-
content=json.dumps(tool_output, ensure_ascii=False) or "<unknown_tool_output>"
65+
content=safe_json_serialize(tool_output) or "<unknown_tool_output>"
6766
)
6867

6968

veadk/utils/misc.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import importlib.util
16+
import json
1617
import sys
1718
import time
1819
import types
@@ -81,3 +82,21 @@ def flatten_dict(
8182
else:
8283
items.append((new_key, v))
8384
return dict(items)
85+
86+
87+
def safe_json_serialize(obj) -> str:
88+
"""Convert any Python object to a JSON-serializable type or string.
89+
90+
Args:
91+
obj: The object to serialize.
92+
93+
Returns:
94+
The JSON-serialized object string or <non-serializable> if the object cannot be serialized.
95+
"""
96+
97+
try:
98+
return json.dumps(
99+
obj, ensure_ascii=False, default=lambda o: "<not serializable>"
100+
)
101+
except (TypeError, OverflowError):
102+
return "<not serializable>"

0 commit comments

Comments
 (0)