@sentry/core
Version:
Base implementation for all Sentry JavaScript SDKs
143 lines (131 loc) • 4.13 kB
JavaScript
import { OPENAI_OPERATIONS, GEN_AI_RESPONSE_ID_ATTRIBUTE, OPENAI_RESPONSE_ID_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, OPENAI_RESPONSE_MODEL_ATTRIBUTE, OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE } from '../gen-ai-attributes.js';
import { INSTRUMENTED_METHODS } from './constants.js';
/**
* Maps OpenAI method paths to Sentry operation names
*/
function getOperationName(methodPath) {
if (methodPath.includes('chat.completions')) {
return OPENAI_OPERATIONS.CHAT;
}
if (methodPath.includes('responses')) {
return OPENAI_OPERATIONS.RESPONSES;
}
return methodPath.split('.').pop() || 'unknown';
}
/**
* Get the span operation for OpenAI methods
* Following Sentry's convention: "gen_ai.{operation_name}"
*/
function getSpanOperation(methodPath) {
return `gen_ai.${getOperationName(methodPath)}`;
}
/**
* Check if a method path should be instrumented
*/
function shouldInstrument(methodPath) {
return INSTRUMENTED_METHODS.includes(methodPath );
}
/**
* Build method path from current traversal
*/
function buildMethodPath(currentPath, prop) {
return currentPath ? `${currentPath}.${prop}` : prop;
}
/**
* Check if response is a Chat Completion object
*/
function isChatCompletionResponse(response) {
return (
response !== null &&
typeof response === 'object' &&
'object' in response &&
(response ).object === 'chat.completion'
);
}
/**
* Check if response is a Responses API object
*/
function isResponsesApiResponse(response) {
return (
response !== null &&
typeof response === 'object' &&
'object' in response &&
(response ).object === 'response'
);
}
/**
* Check if streaming event is from the Responses API
*/
function isResponsesApiStreamEvent(event) {
return (
event !== null &&
typeof event === 'object' &&
'type' in event &&
typeof (event ).type === 'string' &&
((event ).type ).startsWith('response.')
);
}
/**
* Check if streaming event is a chat completion chunk
*/
function isChatCompletionChunk(event) {
return (
event !== null &&
typeof event === 'object' &&
'object' in event &&
(event ).object === 'chat.completion.chunk'
);
}
/**
* Set token usage attributes
* @param span - The span to add attributes to
* @param promptTokens - The number of prompt tokens
* @param completionTokens - The number of completion tokens
* @param totalTokens - The number of total tokens
*/
function setTokenUsageAttributes(
span,
promptTokens,
completionTokens,
totalTokens,
) {
if (promptTokens !== undefined) {
span.setAttributes({
[ ]: promptTokens,
[ ]: promptTokens,
});
}
if (completionTokens !== undefined) {
span.setAttributes({
[ ]: completionTokens,
[ ]: completionTokens,
});
}
if (totalTokens !== undefined) {
span.setAttributes({
[ ]: totalTokens,
});
}
}
/**
* Set common response attributes
* @param span - The span to add attributes to
* @param id - The response id
* @param model - The response model
* @param timestamp - The response timestamp
*/
function setCommonResponseAttributes(span, id, model, timestamp) {
span.setAttributes({
[ ]: id,
[ ]: id,
});
span.setAttributes({
[ ]: model,
[ ]: model,
});
span.setAttributes({
[ ]: new Date(timestamp * 1000).toISOString(),
});
}
export { buildMethodPath, getOperationName, getSpanOperation, isChatCompletionChunk, isChatCompletionResponse, isResponsesApiResponse, isResponsesApiStreamEvent, setCommonResponseAttributes, setTokenUsageAttributes, shouldInstrument };
//# sourceMappingURL=utils.js.map