Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions tests/test_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,12 @@ async def test_cloud():
mock_vefaas_client = Mock()
mock_vefaas_in_app.return_value = mock_vefaas_client
mock_vefaas_client.delete.return_value = None

cloud_app.delete_self()
mock_vefaas_client.delete.assert_called_with("app-123")
with patch.object(
cloud_app, "_get_vefaas_application_id_by_name"
) as mock_get_id_by_name:
mock_get_id_by_name.return_value = None
cloud_app.delete_self()
mock_vefaas_client.delete.assert_called_with("app-123")

# Verify all mocks were called as expected
mock_vefaas_service.deploy.assert_called_once()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
ExtractorResponse,
LLMAttributesParams,
)
from veadk.utils.misc import safe_json_serialize


def llm_gen_ai_request_model(params: LLMAttributesParams) -> ExtractorResponse:
Expand Down Expand Up @@ -133,7 +134,7 @@ def llm_gen_ai_prompt(params: LLMAttributesParams) -> ExtractorResponse:
else "<unknown_function_name>"
)
message[f"gen_ai.prompt.{idx}.tool_calls.0.function.arguments"] = (
json.dumps(part.function_call.args)
safe_json_serialize(part.function_call.args)
if part.function_call.args
else json.dumps({})
)
Expand Down Expand Up @@ -168,7 +169,7 @@ def llm_gen_ai_completion(params: LLMAttributesParams) -> ExtractorResponse:
else "<unknown_function_name>"
)
message[f"gen_ai.completion.{idx}.tool_calls.0.function.arguments"] = (
json.dumps(part.function_call.args)
safe_json_serialize(part.function_call.args)
if part.function_call.args
else json.dumps({})
)
Expand Down Expand Up @@ -289,7 +290,7 @@ def llm_gen_ai_assistant_message(params: LLMAttributesParams) -> ExtractorRespon
else "<unknown_function_name>"
)
message_part["tool_calls.0.function.arguments"] = (
json.dumps(part.function_call.args)
safe_json_serialize(part.function_call.args)
if part.function_call.args
else json.dumps({})
)
Expand Down Expand Up @@ -326,7 +327,7 @@ def llm_gen_ai_choice(params: LLMAttributesParams) -> ExtractorResponse:
else "<unknown_function_name>"
)
message["message.tool_calls.0.function.arguments"] = (
json.dumps(part.function_call.args)
safe_json_serialize(part.function_call.args)
if part.function_call.args
else json.dumps({})
)
Expand All @@ -351,7 +352,7 @@ def llm_gen_ai_choice(params: LLMAttributesParams) -> ExtractorResponse:
else "<unknown_function_name>"
)
message["message.tool_calls.0.function.arguments"] = (
json.dumps(part.function_call.args)
safe_json_serialize(part.function_call.args)
if part.function_call.args
else json.dumps({})
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import json

from veadk.tracing.telemetry.attributes.extractors.types import (
ExtractorResponse,
ToolAttributesParams,
)
from veadk.utils.misc import safe_json_serialize


def tool_gen_ai_operation_name(params: ToolAttributesParams) -> ExtractorResponse:
Expand All @@ -27,7 +26,7 @@ def tool_gen_ai_operation_name(params: ToolAttributesParams) -> ExtractorRespons
def tool_gen_ai_tool_message(params: ToolAttributesParams) -> ExtractorResponse:
tool_input = {
"role": "tool",
"content": json.dumps(
"content": safe_json_serialize(
{
"name": params.tool.name,
"description": params.tool.description,
Expand All @@ -45,7 +44,7 @@ def tool_gen_ai_tool_input(params: ToolAttributesParams) -> ExtractorResponse:
"parameters": params.args,
}
return ExtractorResponse(
content=json.dumps(tool_input, ensure_ascii=False) or "<unknown_tool_input>"
content=safe_json_serialize(tool_input) or "<unknown_tool_input>"
)


Expand All @@ -63,7 +62,7 @@ def tool_gen_ai_tool_output(params: ToolAttributesParams) -> ExtractorResponse:
"response": function_response["response"],
}
return ExtractorResponse(
content=json.dumps(tool_output, ensure_ascii=False) or "<unknown_tool_output>"
content=safe_json_serialize(tool_output) or "<unknown_tool_output>"
)


Expand Down
19 changes: 19 additions & 0 deletions veadk/utils/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

import importlib.util
import json
import sys
import time
import types
Expand Down Expand Up @@ -81,3 +82,21 @@ def flatten_dict(
else:
items.append((new_key, v))
return dict(items)


def safe_json_serialize(obj) -> str:
"""Convert any Python object to a JSON-serializable type or string.

Args:
obj: The object to serialize.

Returns:
The JSON-serialized object string or <non-serializable> if the object cannot be serialized.
"""

try:
return json.dumps(
obj, ensure_ascii=False, default=lambda o: "<not serializable>"
)
except (TypeError, OverflowError):
return "<not serializable>"