Skip to content

Commit 90359e4

Browse files
committed
Move addXAttributes to utils
1 parent 1fd3d67 commit 90359e4

File tree

2 files changed

+100
-100
lines changed

2 files changed

+100
-100
lines changed

packages/core/src/tracing/openai/index.ts

Lines changed: 3 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,18 @@ import {
1616
GEN_AI_REQUEST_STREAM_ATTRIBUTE,
1717
GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE,
1818
GEN_AI_REQUEST_TOP_P_ATTRIBUTE,
19-
GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,
20-
GEN_AI_RESPONSE_MODEL_ATTRIBUTE,
2119
GEN_AI_RESPONSE_TEXT_ATTRIBUTE,
22-
GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,
2320
GEN_AI_SYSTEM_ATTRIBUTE,
24-
OPENAI_RESPONSE_MODEL_ATTRIBUTE,
2521
} from '../ai/gen-ai-attributes';
2622
import { getTruncatedJsonString } from '../ai/utils';
2723
import { OPENAI_INTEGRATION_NAME } from './constants';
2824
import { instrumentStream } from './streaming';
2925
import type {
3026
ChatCompletionChunk,
3127
InstrumentedMethod,
32-
OpenAiChatCompletionObject,
33-
OpenAICreateEmbeddingsObject,
3428
OpenAiIntegration,
3529
OpenAiOptions,
3630
OpenAiResponse,
37-
OpenAIResponseObject,
3831
OpenAIStream,
3932
ResponseStreamingEvent,
4033
} from './types';
@@ -45,8 +38,9 @@ import {
4538
isChatCompletionResponse,
4639
isEmbeddingsResponse,
4740
isResponsesApiResponse,
48-
setCommonResponseAttributes,
49-
setTokenUsageAttributes,
41+
addChatCompletionAttributes,
42+
addResponsesApiAttributes,
43+
addEmbeddingsAttributes,
5044
shouldInstrument,
5145
} from './utils';
5246

@@ -97,97 +91,6 @@ function extractRequestAttributes(args: unknown[], methodPath: string): Record<s
9791
return attributes;
9892
}
9993

100-
/**
101-
* Add attributes for Chat Completion responses
102-
*/
103-
function addChatCompletionAttributes(span: Span, response: OpenAiChatCompletionObject, recordOutputs?: boolean): void {
104-
setCommonResponseAttributes(span, response.id, response.model, response.created);
105-
if (response.usage) {
106-
setTokenUsageAttributes(
107-
span,
108-
response.usage.prompt_tokens,
109-
response.usage.completion_tokens,
110-
response.usage.total_tokens,
111-
);
112-
}
113-
if (Array.isArray(response.choices)) {
114-
const finishReasons = response.choices
115-
.map(choice => choice.finish_reason)
116-
.filter((reason): reason is string => reason !== null);
117-
if (finishReasons.length > 0) {
118-
span.setAttributes({
119-
[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify(finishReasons),
120-
});
121-
}
122-
123-
// Extract tool calls from all choices (only if recordOutputs is true)
124-
if (recordOutputs) {
125-
const toolCalls = response.choices
126-
.map(choice => choice.message?.tool_calls)
127-
.filter(calls => Array.isArray(calls) && calls.length > 0)
128-
.flat();
129-
130-
if (toolCalls.length > 0) {
131-
span.setAttributes({
132-
[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(toolCalls),
133-
});
134-
}
135-
}
136-
}
137-
}
138-
139-
/**
140-
* Add attributes for Responses API responses
141-
*/
142-
function addResponsesApiAttributes(span: Span, response: OpenAIResponseObject, recordOutputs?: boolean): void {
143-
setCommonResponseAttributes(span, response.id, response.model, response.created_at);
144-
if (response.status) {
145-
span.setAttributes({
146-
[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify([response.status]),
147-
});
148-
}
149-
if (response.usage) {
150-
setTokenUsageAttributes(
151-
span,
152-
response.usage.input_tokens,
153-
response.usage.output_tokens,
154-
response.usage.total_tokens,
155-
);
156-
}
157-
158-
// Extract function calls from output (only if recordOutputs is true)
159-
if (recordOutputs) {
160-
const responseWithOutput = response as OpenAIResponseObject & { output?: unknown[] };
161-
if (Array.isArray(responseWithOutput.output) && responseWithOutput.output.length > 0) {
162-
// Filter for function_call type objects in the output array
163-
const functionCalls = responseWithOutput.output.filter(
164-
(item): unknown =>
165-
typeof item === 'object' && item !== null && (item as Record<string, unknown>).type === 'function_call',
166-
);
167-
168-
if (functionCalls.length > 0) {
169-
span.setAttributes({
170-
[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(functionCalls),
171-
});
172-
}
173-
}
174-
}
175-
}
176-
177-
/**
178-
* Add attributes for Embeddings API responses
179-
*/
180-
function addEmbeddingsAttributes(span: Span, response: OpenAICreateEmbeddingsObject): void {
181-
span.setAttributes({
182-
[OPENAI_RESPONSE_MODEL_ATTRIBUTE]: response.model,
183-
[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model,
184-
});
185-
186-
if (response.usage) {
187-
setTokenUsageAttributes(span, response.usage.prompt_tokens, undefined, response.usage.total_tokens);
188-
}
189-
}
190-
19194
/**
19295
* Add response attributes to spans
19396
* This currently supports both Chat Completion and Responses API responses

packages/core/src/tracing/openai/utils.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,
66
GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,
77
GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,
8+
GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,
9+
GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,
810
OPENAI_OPERATIONS,
911
OPENAI_RESPONSE_ID_ATTRIBUTE,
1012
OPENAI_RESPONSE_MODEL_ATTRIBUTE,
@@ -121,6 +123,101 @@ export function isChatCompletionChunk(event: unknown): event is ChatCompletionCh
121123
);
122124
}
123125

126+
/**
127+
* Add attributes for Chat Completion responses
128+
*/
129+
export function addChatCompletionAttributes(
130+
span: Span,
131+
response: OpenAiChatCompletionObject,
132+
recordOutputs?: boolean,
133+
): void {
134+
setCommonResponseAttributes(span, response.id, response.model, response.created);
135+
if (response.usage) {
136+
setTokenUsageAttributes(
137+
span,
138+
response.usage.prompt_tokens,
139+
response.usage.completion_tokens,
140+
response.usage.total_tokens,
141+
);
142+
}
143+
if (Array.isArray(response.choices)) {
144+
const finishReasons = response.choices
145+
.map(choice => choice.finish_reason)
146+
.filter((reason): reason is string => reason !== null);
147+
if (finishReasons.length > 0) {
148+
span.setAttributes({
149+
[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify(finishReasons),
150+
});
151+
}
152+
153+
// Extract tool calls from all choices (only if recordOutputs is true)
154+
if (recordOutputs) {
155+
const toolCalls = response.choices
156+
.map(choice => choice.message?.tool_calls)
157+
.filter(calls => Array.isArray(calls) && calls.length > 0)
158+
.flat();
159+
160+
if (toolCalls.length > 0) {
161+
span.setAttributes({
162+
[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(toolCalls),
163+
});
164+
}
165+
}
166+
}
167+
}
168+
169+
/**
170+
* Add attributes for Responses API responses
171+
*/
172+
export function addResponsesApiAttributes(span: Span, response: OpenAIResponseObject, recordOutputs?: boolean): void {
173+
setCommonResponseAttributes(span, response.id, response.model, response.created_at);
174+
if (response.status) {
175+
span.setAttributes({
176+
[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify([response.status]),
177+
});
178+
}
179+
if (response.usage) {
180+
setTokenUsageAttributes(
181+
span,
182+
response.usage.input_tokens,
183+
response.usage.output_tokens,
184+
response.usage.total_tokens,
185+
);
186+
}
187+
188+
// Extract function calls from output (only if recordOutputs is true)
189+
if (recordOutputs) {
190+
const responseWithOutput = response as OpenAIResponseObject & { output?: unknown[] };
191+
if (Array.isArray(responseWithOutput.output) && responseWithOutput.output.length > 0) {
192+
// Filter for function_call type objects in the output array
193+
const functionCalls = responseWithOutput.output.filter(
194+
(item): unknown =>
195+
typeof item === 'object' && item !== null && (item as Record<string, unknown>).type === 'function_call',
196+
);
197+
198+
if (functionCalls.length > 0) {
199+
span.setAttributes({
200+
[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(functionCalls),
201+
});
202+
}
203+
}
204+
}
205+
}
206+
207+
/**
208+
* Add attributes for Embeddings API responses
209+
*/
210+
export function addEmbeddingsAttributes(span: Span, response: OpenAICreateEmbeddingsObject): void {
211+
span.setAttributes({
212+
[OPENAI_RESPONSE_MODEL_ATTRIBUTE]: response.model,
213+
[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model,
214+
});
215+
216+
if (response.usage) {
217+
setTokenUsageAttributes(span, response.usage.prompt_tokens, undefined, response.usage.total_tokens);
218+
}
219+
}
220+
124221
/**
125222
* Set token usage attributes
126223
* @param span - The span to add attributes to

0 commit comments

Comments
 (0)