Skip to content

Commit 5e562b2

Browse files
zurdoooBridgeAR
authored andcommitted
fixed asserts in testing file (#8862)
1 parent 34db6f8 commit 5e562b2

5 files changed

Lines changed: 160 additions & 4 deletions

File tree

packages/dd-trace/src/llmobs/plugins/genai/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const {
55
getOperation,
66
extractMetrics,
77
extractMetadata,
8+
extractToolDefinitions,
89
aggregateStreamingChunks,
910
formatInputMessages,
1011
formatEmbeddingInput,
@@ -79,6 +80,9 @@ class GenAiLLMObsPlugin extends LLMObsPlugin {
7980
const metadata = extractMetadata(config)
8081
this._tagger.tagMetadata(span, metadata)
8182

83+
const toolDefinitions = extractToolDefinitions(config)
84+
if (toolDefinitions.length > 0) this._tagger.tagToolDefinitions(span, toolDefinitions)
85+
8286
if (error) {
8387
this._tagger.tagLLMIO(span, inputMessages, [{ content: '' }])
8488
return

packages/dd-trace/src/llmobs/plugins/genai/util.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,50 @@ function extractMetadata (config) {
155155
return metadata
156156
}
157157

158+
/**
159+
* Extract tool definitions from config
160+
* @param {object} config
161+
* @returns {Array}
162+
*/
163+
function extractToolDefinitions (config) {
164+
const toolDefinitions = []
165+
166+
if (!Array.isArray(config?.tools)) {
167+
return toolDefinitions
168+
}
169+
170+
for (const tool of config.tools) {
171+
// Only extract tools with valid function declarations
172+
if (!Array.isArray(tool?.functionDeclarations)) {
173+
continue
174+
}
175+
176+
for (const currDeclaration of tool.functionDeclarations) {
177+
// A valid declaration must have a name
178+
if (!currDeclaration?.name) {
179+
continue
180+
}
181+
182+
const toolDef = { name: currDeclaration.name }
183+
184+
if (currDeclaration.description !== undefined) {
185+
toolDef.description = currDeclaration.description
186+
}
187+
188+
// Parameters can be in two different fields depending on user input
189+
if (currDeclaration.parameters !== undefined) {
190+
toolDef.schema = currDeclaration.parameters
191+
} else if (currDeclaration.parametersJsonSchema !== undefined) {
192+
toolDef.schema = currDeclaration.parametersJsonSchema
193+
}
194+
195+
toolDefinitions.push(toolDef)
196+
}
197+
}
198+
199+
return toolDefinitions
200+
}
201+
158202
/**
159203
* Format function call message
160204
* @param {Array} parts
@@ -498,6 +542,7 @@ module.exports = {
498542
getOperation,
499543
extractMetrics,
500544
extractMetadata,
545+
extractToolDefinitions,
501546
aggregateStreamingChunks,
502547
formatInputMessages,
503548
formatEmbeddingInput,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"request": {
3+
"method": "POST",
4+
"url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent",
5+
"headers": {
6+
"Connection": "keep-alive",
7+
"User-Agent": "google-genai-sdk/1.19.0 gl-node/v26.0.0",
8+
"x-goog-api-client": "google-genai-sdk/1.19.0 gl-node/v26.0.0",
9+
"Content-Type": "application/json",
10+
"Accept": "*/*",
11+
"Accept-Language": "*",
12+
"sec-fetch-mode": "cors",
13+
"Accept-Encoding": "gzip, deflate",
14+
"Content-Length": "300"
15+
},
16+
"body": "{\"contents\":[{\"parts\":[{\"text\":\"Hello, world!\"}],\"role\":\"user\"}],\"tools\":[{\"functionDeclarations\":[{\"description\":\"A simple tool\",\"name\":\"tool1\",\"parameters\":{\"type\":\"OBJECT\",\"properties\":{\"location\":{\"type\":\"STRING\",\"description\":\"The city name\"}},\"required\":[\"location\"]}}]}],\"generationConfig\":{}}"
17+
},
18+
"response": {
19+
"status": {
20+
"code": 200,
21+
"message": "OK"
22+
},
23+
"headers": {
24+
"X-Gemini-Service-Tier": "standard",
25+
"Content-Type": "application/json; charset=UTF-8",
26+
"Vary": "Origin, X-Origin, Referer",
27+
"Content-Encoding": "gzip",
28+
"Date": "Wed, 10 Jun 2026 15:36:39 GMT",
29+
"Server": "scaffolding on HTTPServer2",
30+
"X-XSS-Protection": "0",
31+
"X-Frame-Options": "SAMEORIGIN",
32+
"X-Content-Type-Options": "nosniff",
33+
"Server-Timing": "gfet4t7; dur=421",
34+
"Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000",
35+
"Transfer-Encoding": "chunked"
36+
},
37+
"body": "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\": [\n {\n \"text\": \"Hello! How can I help you today?\\n\"\n }\n ],\n \"role\": \"model\"\n },\n \"finishReason\": \"STOP\",\n \"index\": 0\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\": 41,\n \"candidatesTokenCount\": 9,\n \"totalTokenCount\": 50,\n \"promptTokensDetails\": [\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 41\n }\n ],\n \"serviceTier\": \"standard\"\n },\n \"modelVersion\": \"gemini-2.5-flash\",\n \"responseId\": \"h4QpaqGNG8Wu_PUP7JaUmQE\"\n}\n"
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"request": {
3+
"method": "POST",
4+
"url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse",
5+
"headers": {
6+
"Connection": "keep-alive",
7+
"User-Agent": "google-genai-sdk/1.19.0 gl-node/v26.0.0",
8+
"x-goog-api-client": "google-genai-sdk/1.19.0 gl-node/v26.0.0",
9+
"Content-Type": "application/json",
10+
"Accept": "*/*",
11+
"Accept-Language": "*",
12+
"sec-fetch-mode": "cors",
13+
"Accept-Encoding": "gzip, deflate",
14+
"Content-Length": "65"
15+
},
16+
"body": "{\"contents\":[{\"parts\":[{\"text\":\"Hello, world!\"}],\"role\":\"user\"}]}"
17+
},
18+
"response": {
19+
"status": {
20+
"code": 200,
21+
"message": "OK"
22+
},
23+
"headers": {
24+
"Content-Type": "text/event-stream",
25+
"Content-Disposition": "attachment",
26+
"Vary": "Origin, X-Origin, Referer",
27+
"Transfer-Encoding": "chunked",
28+
"Date": "Wed, 10 Jun 2026 14:40:52 GMT",
29+
"Server": "scaffolding on HTTPServer2",
30+
"X-XSS-Protection": "0",
31+
"X-Frame-Options": "SAMEORIGIN",
32+
"X-Content-Type-Options": "nosniff",
33+
"Server-Timing": "gfet4t7; dur=829",
34+
"Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000"
35+
},
36+
"body": "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"Hello, world! It's good to meet you. How can I help you today?\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 5,\"candidatesTokenCount\": 19,\"totalTokenCount\": 53,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 5}],\"thoughtsTokenCount\": 29,\"serviceTier\": \"standard\"},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"c3cpap_xFpLRjMcPt5CUwQw\"}\r\n\r\n"
37+
}
38+
}

packages/dd-trace/test/llmobs/plugins/google-genai/index.spec.js

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,27 @@ describe('Plugin', () => {
2828
describe('models.generateContent', () => {
2929
it('creates a span', async () => {
3030
const result = await client.models.generateContent({
31-
model: 'gemini-2.0-flash',
31+
model: 'gemini-2.5-flash',
3232
contents: 'Hello, world!',
33+
config: {
34+
tools: [
35+
{
36+
functionDeclarations: [
37+
{
38+
name: 'tool1',
39+
description: 'A simple tool',
40+
parameters: {
41+
type: 'object',
42+
properties: {
43+
location: { type: 'string', description: 'The city name' },
44+
},
45+
required: ['location'],
46+
},
47+
},
48+
],
49+
},
50+
],
51+
},
3352
})
3453

3554
assert.ok(result)
@@ -39,7 +58,7 @@ describe('Plugin', () => {
3958
span: apmSpans[0],
4059
spanKind: 'llm',
4160
name: 'google_genai.request',
42-
modelName: 'gemini-2.0-flash',
61+
modelName: 'gemini-2.5-flash',
4362
modelProvider: 'google',
4463
inputMessages: [{ role: 'user', content: 'Hello, world!' }],
4564
outputMessages: [{ role: 'assistant', content: MOCK_STRING }],
@@ -64,6 +83,17 @@ describe('Plugin', () => {
6483
output_tokens: MOCK_NUMBER,
6584
total_tokens: MOCK_NUMBER,
6685
},
86+
toolDefinitions: [{
87+
name: 'tool1',
88+
description: 'A simple tool',
89+
schema: {
90+
type: 'OBJECT',
91+
properties: {
92+
location: { type: 'STRING', description: 'The city name' },
93+
},
94+
required: ['location'],
95+
},
96+
}],
6797
tags: { ml_app: 'test', integration: 'google_genai' },
6898
})
6999
})
@@ -72,7 +102,7 @@ describe('Plugin', () => {
72102
describe('models.generateContentStream', () => {
73103
it('creates a span', async () => {
74104
const stream = await client.models.generateContentStream({
75-
model: 'gemini-2.0-flash',
105+
model: 'gemini-2.5-flash',
76106
contents: 'Hello, world!',
77107
})
78108

@@ -85,7 +115,7 @@ describe('Plugin', () => {
85115
span: apmSpans[0],
86116
spanKind: 'llm',
87117
name: 'google_genai.request',
88-
modelName: 'gemini-2.0-flash',
118+
modelName: 'gemini-2.5-flash',
89119
modelProvider: 'google',
90120
inputMessages: [{ role: 'user', content: 'Hello, world!' }],
91121
outputMessages: [{ role: 'assistant', content: MOCK_STRING }],

0 commit comments

Comments
 (0)