1818from volcenginesdkarkruntime import Ark
1919from veadk .config import getenv
2020import base64
21-
21+ from opentelemetry import trace
22+ import traceback
23+ import json
24+ from veadk .version import VERSION
25+ from opentelemetry .trace import Span
2226from veadk .utils .logger import get_logger
2327
2428logger = get_logger (__name__ )
@@ -100,45 +104,70 @@ async def image_edit(
100104 seed = item .get ("seed" , - 1 )
101105
102106 try :
103- response = client .images .generate (
104- model = getenv ("MODEL_EDIT_NAME" ),
105- image = origin_image ,
106- prompt = prompt ,
107- response_format = response_format ,
108- guidance_scale = guidance_scale ,
109- watermark = watermark ,
110- seed = seed ,
111- )
112-
113- if response .data and len (response .data ) > 0 :
114- for item in response .data :
115- if response_format == "url" :
116- image = item .url
117- tool_context .state [f"{ image_name } _url" ] = image
118-
119- elif response_format == "b64_json" :
120- image = item .b64_json
121- image_bytes = base64 .b64decode (image )
122-
123- tool_context .state [f"{ image_name } _url" ] = (
124- f"data:image/jpeg;base64,{ image } "
125- )
126-
127- report_artifact = types .Part .from_bytes (
128- data = image_bytes , mime_type = "image/png"
129- )
130- await tool_context .save_artifact (image_name , report_artifact )
131- logger .debug (f"Image saved as ADK artifact: { image_name } " )
132-
133- success_list .append ({image_name : image })
134- else :
135- error_details = f"No images returned by Doubao model: { response } "
136- logger .error (error_details )
137- error_list .append (image_name )
107+ tracer = trace .get_tracer ("gcp.vertex.agent" )
108+ with tracer .start_as_current_span ("call_llm" ) as span :
109+ inputs = {
110+ "prompt" : prompt ,
111+ "image" : origin_image ,
112+ "response_format" : response_format ,
113+ "guidance_scale" : guidance_scale ,
114+ "watermark" : watermark ,
115+ "seed" : seed ,
116+ }
117+ input_part = {
118+ "role" : "user" ,
119+ "content" : json .dumps (inputs , ensure_ascii = False ),
120+ }
121+ response = client .images .generate (
122+ model = getenv ("MODEL_EDIT_NAME" ), ** inputs
123+ )
124+ output_part = None
125+ if response .data and len (response .data ) > 0 :
126+ for item in response .data :
127+ if response_format == "url" :
128+ image = item .url
129+ tool_context .state [f"{ image_name } _url" ] = image
130+ output_part = {
131+ "message.role" : "model" ,
132+ "message.content" : image ,
133+ }
134+ elif response_format == "b64_json" :
135+ image = item .b64_json
136+ image_bytes = base64 .b64decode (image )
137+
138+ tool_context .state [f"{ image_name } _url" ] = (
139+ f"data:image/jpeg;base64,{ image } "
140+ )
141+
142+ report_artifact = types .Part .from_bytes (
143+ data = image_bytes , mime_type = "image/png"
144+ )
145+ await tool_context .save_artifact (
146+ image_name , report_artifact
147+ )
148+ logger .debug (f"Image saved as ADK artifact: { image_name } " )
149+
150+ success_list .append ({image_name : image })
151+ else :
152+ error_details = f"No images returned by Doubao model: { response } "
153+ logger .error (error_details )
154+ error_list .append (image_name )
155+
156+ add_span_attributes (
157+ span ,
158+ tool_context ,
159+ input_part = input_part ,
160+ output_part = output_part ,
161+ output_tokens = response .usage .output_tokens ,
162+ total_tokens = response .usage .total_tokens ,
163+ request_model = getenv ("MODEL_EDIT_NAME" ),
164+ response_model = getenv ("MODEL_EDIT_NAME" ),
165+ )
138166
139167 except Exception as e :
140168 error_details = f"No images returned by Doubao model: { e } "
141169 logger .error (error_details )
170+ traceback .print_exc ()
142171 error_list .append (image_name )
143172
144173 if len (success_list ) == 0 :
@@ -153,3 +182,55 @@ async def image_edit(
153182 "success_list" : success_list ,
154183 "error_list" : error_list ,
155184 }
185+
186+
187+ def add_span_attributes (
188+ span : Span ,
189+ tool_context : ToolContext ,
190+ input_part : dict = None ,
191+ output_part : dict = None ,
192+ input_tokens : int = None ,
193+ output_tokens : int = None ,
194+ total_tokens : int = None ,
195+ request_model : str = None ,
196+ response_model : str = None ,
197+ ):
198+ try :
199+ # common attributes
200+ app_name = tool_context ._invocation_context .app_name
201+ user_id = tool_context ._invocation_context .user_id
202+ agent_name = tool_context .agent_name
203+ session_id = tool_context ._invocation_context .session .id
204+ span .set_attribute ("gen_ai.agent.name" , agent_name )
205+ span .set_attribute ("openinference.instrumentation.veadk" , VERSION )
206+ span .set_attribute ("gen_ai.app.name" , app_name )
207+ span .set_attribute ("gen_ai.user.id" , user_id )
208+ span .set_attribute ("gen_ai.session.id" , session_id )
209+ span .set_attribute ("agent_name" , agent_name )
210+ span .set_attribute ("agent.name" , agent_name )
211+ span .set_attribute ("app_name" , app_name )
212+ span .set_attribute ("app.name" , app_name )
213+ span .set_attribute ("user.id" , user_id )
214+ span .set_attribute ("session.id" , session_id )
215+ span .set_attribute ("cozeloop.report.source" , "veadk" )
216+
217+ # llm attributes
218+ span .set_attribute ("gen_ai.system" , "openai" )
219+ span .set_attribute ("gen_ai.operation.name" , "chat" )
220+ if request_model :
221+ span .set_attribute ("gen_ai.request.model" , request_model )
222+ if response_model :
223+ span .set_attribute ("gen_ai.response.model" , response_model )
224+ if total_tokens :
225+ span .set_attribute ("gen_ai.usage.total_tokens" , total_tokens )
226+ if output_tokens :
227+ span .set_attribute ("gen_ai.usage.output_tokens" , output_tokens )
228+ if input_tokens :
229+ span .set_attribute ("gen_ai.usage.input_tokens" , input_tokens )
230+ if input_part :
231+ span .add_event ("gen_ai.user.message" , input_part )
232+ if output_part :
233+ span .add_event ("gen_ai.choice" , output_part )
234+
235+ except Exception :
236+ traceback .print_exc ()
0 commit comments