@@ -279,15 +279,15 @@ class AIGuardInternalTests extends DDSpecification {
279279 final requestContext = Mock (RequestContext )
280280 localRootSpan. getRequestContext() >> requestContext
281281 requestContext. getClientIpAddressData() >> new ClientIpAddressData (' 4.4.4.4' , ' 2.3.4.5' )
282+ localRootSpan. getTag(Tags . NETWORK_CLIENT_IP ) >> null
283+ localRootSpan. getTag(Tags . HTTP_CLIENT_IP ) >> null
282284 final aiguard = mockClient(200 , [data : [attributes : [action : ' ALLOW' , reason : ' It is fine' ]]])
283285
284286 when :
285287 aiguard. evaluate(TOOL_CALL , AIGuard.Options . DEFAULT )
286288
287289 then :
288- 1 * localRootSpan. getTag(Tags . NETWORK_CLIENT_IP ) >> null
289290 1 * localRootSpan. setTag(Tags . NETWORK_CLIENT_IP , ' 4.4.4.4' )
290- 1 * localRootSpan. getTag(Tags . HTTP_CLIENT_IP ) >> null
291291 1 * localRootSpan. setTag(Tags . HTTP_CLIENT_IP , ' 2.3.4.5' )
292292 }
293293
@@ -296,15 +296,15 @@ class AIGuardInternalTests extends DDSpecification {
296296 final requestContext = Mock (RequestContext )
297297 localRootSpan. getRequestContext() >> requestContext
298298 requestContext. getClientIpAddressData() >> new ClientIpAddressData (' 4.4.4.4' , ' 2.3.4.5' )
299+ localRootSpan. getTag(Tags . NETWORK_CLIENT_IP ) >> ' 9.9.9.9'
300+ localRootSpan. getTag(Tags . HTTP_CLIENT_IP ) >> ' 8.8.8.8'
299301 final aiguard = mockClient(200 , [data : [attributes : [action : ' ALLOW' , reason : ' It is fine' ]]])
300302
301303 when :
302304 aiguard. evaluate(TOOL_CALL , AIGuard.Options . DEFAULT )
303305
304306 then :
305- 1 * localRootSpan. getTag(Tags . NETWORK_CLIENT_IP ) >> ' 9.9.9.9'
306307 0 * localRootSpan. setTag(Tags . NETWORK_CLIENT_IP , _)
307- 1 * localRootSpan. getTag(Tags . HTTP_CLIENT_IP ) >> ' 8.8.8.8'
308308 0 * localRootSpan. setTag(Tags . HTTP_CLIENT_IP , _)
309309 }
310310
@@ -336,6 +336,46 @@ class AIGuardInternalTests extends DDSpecification {
336336 0 * localRootSpan. setTag(Tags . HTTP_CLIENT_IP , _)
337337 }
338338
339+ void ' test evaluate copies anomaly detection tags from local root span to ai_guard span' () {
340+ given :
341+ localRootSpan. getTag(Tags . HTTP_CLIENT_IP ) >> ' 1.2.3.4'
342+ localRootSpan. getTag(Tags . NETWORK_CLIENT_IP ) >> ' 5.6.7.8'
343+ localRootSpan. getTag(Tags . HTTP_USER_AGENT ) >> ' curl/8.0'
344+ localRootSpan. getTag(' usr.id' ) >> ' u-123'
345+ localRootSpan. getTag(' usr.session_id' ) >> ' s-456'
346+ final aiguard = mockClient(200 , [data : [attributes : [action : ' ALLOW' , reason : ' It is fine' ]]])
347+
348+ when :
349+ aiguard. evaluate(TOOL_CALL , AIGuard.Options . DEFAULT )
350+
351+ then :
352+ 1 * span. setTag(' ai_guard.http.client_ip' , ' 1.2.3.4' )
353+ 1 * span. setTag(' ai_guard.network.client.ip' , ' 5.6.7.8' )
354+ 1 * span. setTag(' ai_guard.http.useragent' , ' curl/8.0' )
355+ 1 * span. setTag(' ai_guard.usr.id' , ' u-123' )
356+ 1 * span. setTag(' ai_guard.usr.session_id' , ' s-456' )
357+ }
358+
359+ void ' test evaluate skips missing anomaly detection tags' () {
360+ given :
361+ localRootSpan. getTag(Tags . HTTP_CLIENT_IP ) >> ' 1.2.3.4'
362+ localRootSpan. getTag(Tags . NETWORK_CLIENT_IP ) >> null
363+ localRootSpan. getTag(Tags . HTTP_USER_AGENT ) >> null
364+ localRootSpan. getTag(' usr.id' ) >> ' u-123'
365+ localRootSpan. getTag(' usr.session_id' ) >> null
366+ final aiguard = mockClient(200 , [data : [attributes : [action : ' ALLOW' , reason : ' It is fine' ]]])
367+
368+ when :
369+ aiguard. evaluate(TOOL_CALL , AIGuard.Options . DEFAULT )
370+
371+ then :
372+ 1 * span. setTag(' ai_guard.http.client_ip' , ' 1.2.3.4' )
373+ 1 * span. setTag(' ai_guard.usr.id' , ' u-123' )
374+ 0 * span. setTag(' ai_guard.network.client.ip' , _)
375+ 0 * span. setTag(' ai_guard.http.useragent' , _)
376+ 0 * span. setTag(' ai_guard.usr.session_id' , _)
377+ }
378+
339379 void ' test evaluate with API errors' () {
340380 given :
341381 final errors = [[status : 400 , title : ' Bad request' ]]
0 commit comments