1- import { SEMANTIC_ATTRIBUTE_SENTRY_OP , SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core' ;
21import { expect , it } from 'vitest' ;
32import {
43 GEN_AI_OPERATION_NAME_ATTRIBUTE ,
@@ -22,61 +21,77 @@ it('traces Google GenAI chat creation and message sending', async () => {
2221 const runner = createRunner ( __dirname )
2322 . ignore ( 'event' )
2423 . expect ( envelope => {
24+ // Transaction item (first item in envelope)
2525 const transactionEvent = envelope [ 1 ] ?. [ 0 ] ?. [ 1 ] as any ;
26-
2726 expect ( transactionEvent . transaction ) . toBe ( 'GET /' ) ;
28- expect ( transactionEvent . spans ) . toEqual (
29- expect . arrayContaining ( [
30- // chat.sendMessage
31- expect . objectContaining ( {
32- data : expect . objectContaining ( {
33- [ GEN_AI_OPERATION_NAME_ATTRIBUTE ] : 'chat' ,
34- [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'gen_ai.chat' ,
35- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.ai.google_genai' ,
36- [ GEN_AI_SYSTEM_ATTRIBUTE ] : 'google_genai' ,
37- [ GEN_AI_REQUEST_MODEL_ATTRIBUTE ] : 'gemini-1.5-pro' ,
38- [ GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE ] : 8 ,
39- [ GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE ] : 12 ,
40- [ GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE ] : 20 ,
41- } ) ,
42- description : 'chat gemini-1.5-pro' ,
43- op : 'gen_ai.chat' ,
44- origin : 'auto.ai.google_genai' ,
45- } ) ,
46- // models.generateContent
47- expect . objectContaining ( {
48- data : expect . objectContaining ( {
49- [ GEN_AI_OPERATION_NAME_ATTRIBUTE ] : 'generate_content' ,
50- [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'gen_ai.generate_content' ,
51- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.ai.google_genai' ,
52- [ GEN_AI_SYSTEM_ATTRIBUTE ] : 'google_genai' ,
53- [ GEN_AI_REQUEST_MODEL_ATTRIBUTE ] : 'gemini-1.5-flash' ,
54- [ GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE ] : 0.7 ,
55- [ GEN_AI_REQUEST_TOP_P_ATTRIBUTE ] : 0.9 ,
56- [ GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE ] : 100 ,
57- [ GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE ] : 8 ,
58- [ GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE ] : 12 ,
59- [ GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE ] : 20 ,
60- } ) ,
61- description : 'generate_content gemini-1.5-flash' ,
62- op : 'gen_ai.generate_content' ,
63- origin : 'auto.ai.google_genai' ,
64- } ) ,
65- // models.embedContent
66- expect . objectContaining ( {
67- data : expect . objectContaining ( {
68- [ GEN_AI_OPERATION_NAME_ATTRIBUTE ] : 'embeddings' ,
69- [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'gen_ai.embeddings' ,
70- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.ai.google_genai' ,
71- [ GEN_AI_SYSTEM_ATTRIBUTE ] : 'google_genai' ,
72- [ GEN_AI_REQUEST_MODEL_ATTRIBUTE ] : 'text-embedding-004' ,
73- } ) ,
74- description : 'embeddings text-embedding-004' ,
75- op : 'gen_ai.embeddings' ,
76- origin : 'auto.ai.google_genai' ,
77- } ) ,
78- ] ) ,
27+
28+ // Span container item (second item in same envelope)
29+ const container = envelope [ 1 ] ?. [ 1 ] ?. [ 1 ] as any ;
30+ expect ( container ) . toBeDefined ( ) ;
31+ const spans = container . items ;
32+
33+ // chat.sendMessage
34+ const chatSpan = spans . find (
35+ ( s : any ) => s . name === 'chat gemini-1.5-pro' && s . attributes ?. [ 'sentry.op' ] ?. value === 'gen_ai.chat' ,
36+ ) ;
37+ expect ( chatSpan ) . toBeDefined ( ) ;
38+ expect ( chatSpan ) . toMatchObject ( {
39+ name : 'chat gemini-1.5-pro' ,
40+ status : 'ok' ,
41+ } ) ;
42+ expect ( chatSpan . attributes ) . toMatchObject ( {
43+ [ GEN_AI_OPERATION_NAME_ATTRIBUTE ] : { type : 'string' , value : 'chat' } ,
44+ 'sentry.op' : { type : 'string' , value : 'gen_ai.chat' } ,
45+ 'sentry.origin' : { type : 'string' , value : 'auto.ai.google_genai' } ,
46+ [ GEN_AI_SYSTEM_ATTRIBUTE ] : { type : 'string' , value : 'google_genai' } ,
47+ [ GEN_AI_REQUEST_MODEL_ATTRIBUTE ] : { type : 'string' , value : 'gemini-1.5-pro' } ,
48+ [ GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE ] : { type : 'integer' , value : 8 } ,
49+ [ GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE ] : { type : 'integer' , value : 12 } ,
50+ [ GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE ] : { type : 'integer' , value : 20 } ,
51+ } ) ;
52+
53+ // models.generateContent
54+ const generateSpan = spans . find (
55+ ( s : any ) =>
56+ s . name === 'generate_content gemini-1.5-flash' &&
57+ s . attributes ?. [ 'sentry.op' ] ?. value === 'gen_ai.generate_content' ,
58+ ) ;
59+ expect ( generateSpan ) . toBeDefined ( ) ;
60+ expect ( generateSpan ) . toMatchObject ( {
61+ name : 'generate_content gemini-1.5-flash' ,
62+ status : 'ok' ,
63+ } ) ;
64+ expect ( generateSpan . attributes ) . toMatchObject ( {
65+ [ GEN_AI_OPERATION_NAME_ATTRIBUTE ] : { type : 'string' , value : 'generate_content' } ,
66+ 'sentry.op' : { type : 'string' , value : 'gen_ai.generate_content' } ,
67+ 'sentry.origin' : { type : 'string' , value : 'auto.ai.google_genai' } ,
68+ [ GEN_AI_SYSTEM_ATTRIBUTE ] : { type : 'string' , value : 'google_genai' } ,
69+ [ GEN_AI_REQUEST_MODEL_ATTRIBUTE ] : { type : 'string' , value : 'gemini-1.5-flash' } ,
70+ [ GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE ] : { type : 'double' , value : 0.7 } ,
71+ [ GEN_AI_REQUEST_TOP_P_ATTRIBUTE ] : { type : 'double' , value : 0.9 } ,
72+ [ GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE ] : { type : 'integer' , value : 100 } ,
73+ [ GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE ] : { type : 'integer' , value : 8 } ,
74+ [ GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE ] : { type : 'integer' , value : 12 } ,
75+ [ GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE ] : { type : 'integer' , value : 20 } ,
76+ } ) ;
77+
78+ // models.embedContent
79+ const embedSpan = spans . find (
80+ ( s : any ) =>
81+ s . name === 'embeddings text-embedding-004' && s . attributes ?. [ 'sentry.op' ] ?. value === 'gen_ai.embeddings' ,
7982 ) ;
83+ expect ( embedSpan ) . toBeDefined ( ) ;
84+ expect ( embedSpan ) . toMatchObject ( {
85+ name : 'embeddings text-embedding-004' ,
86+ status : 'ok' ,
87+ } ) ;
88+ expect ( embedSpan . attributes ) . toMatchObject ( {
89+ [ GEN_AI_OPERATION_NAME_ATTRIBUTE ] : { type : 'string' , value : 'embeddings' } ,
90+ 'sentry.op' : { type : 'string' , value : 'gen_ai.embeddings' } ,
91+ 'sentry.origin' : { type : 'string' , value : 'auto.ai.google_genai' } ,
92+ [ GEN_AI_SYSTEM_ATTRIBUTE ] : { type : 'string' , value : 'google_genai' } ,
93+ [ GEN_AI_REQUEST_MODEL_ATTRIBUTE ] : { type : 'string' , value : 'text-embedding-004' } ,
94+ } ) ;
8095 } )
8196 . start ( ) ;
8297 await runner . makeRequest ( 'get' , '/' ) ;
0 commit comments