15
15
from __future__ import annotations
16
16
17
17
import logging
18
+ from enum import Enum
18
19
19
20
from google .genai import types as genai_types
20
21
from opentelemetry .util .genai .types import (
22
+ FinishReason ,
21
23
InputMessage ,
22
- OutputMessage ,
23
24
MessagePart ,
24
- FinishReason ,
25
+ OutputMessage ,
25
26
Text ,
26
27
ToolCall ,
27
28
ToolCallResponse ,
28
29
)
29
30
30
- from .message_models import (
31
- # BlobPart,
32
- # FileDataPart,
33
- Role ,
34
- )
31
+
32
+ class Role (str , Enum ):
33
+ SYSTEM = "system"
34
+ USER = "user"
35
+ ASSISTANT = "assistant"
36
+ TOOL = "tool"
37
+
35
38
36
39
_logger = logging .getLogger (__name__ )
37
40
41
+
38
42
def to_input_messages (
39
43
* ,
40
44
contents : list [genai_types .Content ],
41
45
) -> list [InputMessage ]:
42
46
return [_to_input_message (content ) for content in contents ]
43
47
48
+
44
49
def to_output_messages (
45
50
* ,
46
51
candidates : list [genai_types .Candidate ],
@@ -58,32 +63,29 @@ def content_to_output_message(
58
63
parts = message .parts ,
59
64
)
60
65
61
- messages = (
62
- content_to_output_message (candidate ) for candidate in candidates
63
- )
66
+ messages = (content_to_output_message (candidate ) for candidate in candidates )
64
67
return [message for message in messages if message is not None ]
65
68
69
+
66
70
def to_system_instructions (
67
71
* ,
68
72
content : genai_types .Content ,
69
73
) -> list [MessagePart ]:
70
- parts = (
71
- _to_part (part , idx ) for idx , part in enumerate (content .parts or [])
72
- )
74
+ parts = (_to_part (part , idx ) for idx , part in enumerate (content .parts or []))
73
75
return [part for part in parts if part is not None ]
74
76
77
+
75
78
def _to_input_message (
76
79
content : genai_types .Content ,
77
80
) -> InputMessage :
78
- parts = (
79
- _to_part (part , idx ) for idx , part in enumerate (content .parts or [])
80
- )
81
+ parts = (_to_part (part , idx ) for idx , part in enumerate (content .parts or []))
81
82
return InputMessage (
82
83
role = _to_role (content .role ),
83
84
# filter Nones
84
85
parts = [part for part in parts if part is not None ],
85
86
)
86
87
88
+
87
89
def _to_part (part : genai_types .Part , idx : int ) -> MessagePart | None :
88
90
def tool_call_id (name : str | None ) -> str :
89
91
if name :
@@ -93,30 +95,23 @@ def tool_call_id(name: str | None) -> str:
93
95
if (text := part .text ) is not None :
94
96
return Text (content = text )
95
97
96
- # if data := part.inline_data: # TODO ???
97
- # return BlobPart(mime_type=data.mime_type or "", data=data.data or b"")
98
-
99
- # if data := part.file_data: # TODO ???
100
- # return FileDataPart(
101
- # mime_type=data.mime_type or "", file_uri=data.file_uri or ""
102
- # )
103
-
104
98
if call := part .function_call :
105
99
return ToolCall (
106
- id = call .id or tool_call_id (call .name ), # TODO ???
100
+ id = call .id or tool_call_id (call .name ),
107
101
name = call .name or "" ,
108
102
arguments = call .args ,
109
103
)
110
104
111
105
if response := part .function_response :
112
106
return ToolCallResponse (
113
- id = response .id or tool_call_id (response .name ), # TODO ???
107
+ id = response .id or tool_call_id (response .name ),
114
108
response = response .response ,
115
109
)
116
110
117
111
_logger .info ("Unknown part dropped from telemetry %s" , part )
118
112
return None
119
113
114
+
120
115
def _to_role (role : str | None ) -> str :
121
116
if role == "user" :
122
117
return Role .USER .value
0 commit comments