@@ -140,9 +140,14 @@ def test_start_model_invoke_span(mock_tracer):
140140 messages = [{"role" : "user" , "content" : [{"text" : "Hello" }]}]
141141 model_id = "test-model"
142142 custom_attrs = {"custom_key" : "custom_value" , "user_id" : "12345" }
143+ system_prompt = "You are a helpful assistant"
143144
144145 span = tracer .start_model_invoke_span (
145- messages = messages , agent_name = "TestAgent" , model_id = model_id , custom_trace_attributes = custom_attrs
146+ messages = messages ,
147+ agent_name = "TestAgent" ,
148+ model_id = model_id ,
149+ custom_trace_attributes = custom_attrs ,
150+ system_prompt = system_prompt ,
146151 )
147152
148153 mock_tracer .start_span .assert_called_once ()
@@ -158,9 +163,14 @@ def test_start_model_invoke_span(mock_tracer):
158163 "agent_name" : "TestAgent" ,
159164 }
160165 )
161- mock_span .add_event .assert_called_with (
162- "gen_ai.user.message" , attributes = {"content" : json .dumps (messages [0 ]["content" ])}
166+
167+ calls = mock_span .add_event .call_args_list
168+ assert len (calls ) == 2
169+ assert calls [0 ] == mock .call (
170+ "gen_ai.system.message" ,
171+ attributes = {"content" : serialize ([{"text" : system_prompt }])},
163172 )
173+ assert calls [1 ] == mock .call ("gen_ai.user.message" , attributes = {"content" : json .dumps (messages [0 ]["content" ])})
164174 assert span is not None
165175
166176
@@ -184,8 +194,11 @@ def test_start_model_invoke_span_latest_conventions(mock_tracer, monkeypatch):
184194 },
185195 ]
186196 model_id = "test-model"
197+ system_prompt = "You are a calculator assistant"
187198
188- span = tracer .start_model_invoke_span (messages = messages , agent_name = "TestAgent" , model_id = model_id )
199+ span = tracer .start_model_invoke_span (
200+ messages = messages , agent_name = "TestAgent" , model_id = model_id , system_prompt = system_prompt
201+ )
189202
190203 mock_tracer .start_span .assert_called_once ()
191204 assert mock_tracer .start_span .call_args [1 ]["name" ] == "chat"
@@ -199,7 +212,16 @@ def test_start_model_invoke_span_latest_conventions(mock_tracer, monkeypatch):
199212 "agent_name" : "TestAgent" ,
200213 }
201214 )
202- mock_span .add_event .assert_called_with (
215+
216+ calls = mock_span .add_event .call_args_list
217+ assert len (calls ) == 2
218+ assert calls [0 ] == mock .call (
219+ "gen_ai.client.inference.operation.details" ,
220+ attributes = {
221+ "gen_ai.system_instructions" : serialize ([{"type" : "text" , "content" : system_prompt }]),
222+ },
223+ )
224+ assert calls [1 ] == mock .call (
203225 "gen_ai.client.inference.operation.details" ,
204226 attributes = {
205227 "gen_ai.input.messages" : serialize (
@@ -226,6 +248,54 @@ def test_start_model_invoke_span_latest_conventions(mock_tracer, monkeypatch):
226248 assert span is not None
227249
228250
251+ def test_start_model_invoke_span_without_system_prompt (mock_tracer ):
252+ """Test that no system prompt event is emitted when system_prompt is None."""
253+ with mock .patch ("strands.telemetry.tracer.trace_api.get_tracer" , return_value = mock_tracer ):
254+ tracer = Tracer ()
255+ tracer .tracer = mock_tracer
256+
257+ mock_span = mock .MagicMock ()
258+ mock_tracer .start_span .return_value = mock_span
259+
260+ messages = [{"role" : "user" , "content" : [{"text" : "Hello" }]}]
261+
262+ span = tracer .start_model_invoke_span (messages = messages , model_id = "test-model" )
263+
264+ assert mock_span .add_event .call_count == 1
265+ mock_span .add_event .assert_called_once_with (
266+ "gen_ai.user.message" , attributes = {"content" : json .dumps (messages [0 ]["content" ])}
267+ )
268+ assert span is not None
269+
270+
271+ def test_start_model_invoke_span_with_system_prompt_content (mock_tracer ):
272+ """Test that system_prompt_content takes priority over system_prompt string."""
273+ with mock .patch ("strands.telemetry.tracer.trace_api.get_tracer" , return_value = mock_tracer ):
274+ tracer = Tracer ()
275+ tracer .tracer = mock_tracer
276+
277+ mock_span = mock .MagicMock ()
278+ mock_tracer .start_span .return_value = mock_span
279+
280+ messages = [{"role" : "user" , "content" : [{"text" : "Hello" }]}]
281+ system_prompt_content = [{"text" : "You are helpful" }, {"text" : "Be concise" }]
282+
283+ span = tracer .start_model_invoke_span (
284+ messages = messages ,
285+ model_id = "test-model" ,
286+ system_prompt = "ignored string" ,
287+ system_prompt_content = system_prompt_content ,
288+ )
289+
290+ calls = mock_span .add_event .call_args_list
291+ assert len (calls ) == 2
292+ assert calls [0 ] == mock .call (
293+ "gen_ai.system.message" ,
294+ attributes = {"content" : serialize (system_prompt_content )},
295+ )
296+ assert span is not None
297+
298+
229299def test_end_model_invoke_span (mock_span ):
230300 """Test ending a model invoke span."""
231301 tracer = Tracer ()
0 commit comments