@arizeai/openinference-instrumentation-openai 1.1.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,123 +1,16 @@
1
- var __extends = (this && this.__extends) || (function () {
2
- var extendStatics = function (d, b) {
3
- extendStatics = Object.setPrototypeOf ||
4
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6
- return extendStatics(d, b);
7
- };
8
- return function (d, b) {
9
- if (typeof b !== "function" && b !== null)
10
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
11
- extendStatics(d, b);
12
- function __() { this.constructor = d; }
13
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
- };
15
- })();
16
- var __assign = (this && this.__assign) || function () {
17
- __assign = Object.assign || function(t) {
18
- for (var s, i = 1, n = arguments.length; i < n; i++) {
19
- s = arguments[i];
20
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
21
- t[p] = s[p];
22
- }
23
- return t;
24
- };
25
- return __assign.apply(this, arguments);
26
- };
27
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
28
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
29
- return new (P || (P = Promise))(function (resolve, reject) {
30
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
31
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
32
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
33
- step((generator = generator.apply(thisArg, _arguments || [])).next());
34
- });
35
- };
36
- var __generator = (this && this.__generator) || function (thisArg, body) {
37
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
38
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
39
- function verb(n) { return function (v) { return step([n, v]); }; }
40
- function step(op) {
41
- if (f) throw new TypeError("Generator is already executing.");
42
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
43
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
44
- if (y = 0, t) op = [op[0] & 2, t.value];
45
- switch (op[0]) {
46
- case 0: case 1: t = op; break;
47
- case 4: _.label++; return { value: op[1], done: false };
48
- case 5: _.label++; y = op[1]; op = [0]; continue;
49
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
50
- default:
51
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
52
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
53
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
54
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
55
- if (t[2]) _.ops.pop();
56
- _.trys.pop(); continue;
57
- }
58
- op = body.call(thisArg, _);
59
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
60
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
61
- }
62
- };
63
- var __rest = (this && this.__rest) || function (s, e) {
64
- var t = {};
65
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
66
- t[p] = s[p];
67
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
68
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
69
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
70
- t[p[i]] = s[p[i]];
71
- }
72
- return t;
73
- };
74
- var __asyncValues = (this && this.__asyncValues) || function (o) {
75
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
76
- var m = o[Symbol.asyncIterator], i;
77
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
78
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
79
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
80
- };
81
- var __read = (this && this.__read) || function (o, n) {
82
- var m = typeof Symbol === "function" && o[Symbol.iterator];
83
- if (!m) return o;
84
- var i = m.call(o), r, ar = [], e;
85
- try {
86
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
87
- }
88
- catch (error) { e = { error: error }; }
89
- finally {
90
- try {
91
- if (r && !r.done && (m = i["return"])) m.call(i);
92
- }
93
- finally { if (e) throw e.error; }
94
- }
95
- return ar;
96
- };
97
- var __values = (this && this.__values) || function(o) {
98
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
99
- if (m) return m.call(o);
100
- if (o && typeof o.length === "number") return {
101
- next: function () {
102
- if (o && i >= o.length) o = void 0;
103
- return { value: o && o[i++], done: !o };
104
- }
105
- };
106
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
107
- };
108
1
  import { InstrumentationBase, InstrumentationNodeModuleDefinition, safeExecuteInTheMiddle, } from "@opentelemetry/instrumentation";
109
2
  import { diag, context, trace, SpanKind, SpanStatusCode, } from "@opentelemetry/api";
110
- import { VERSION } from "./version";
3
+ import { VERSION } from "./version.js";
111
4
  import { SemanticConventions, OpenInferenceSpanKind, MimeType, LLMSystem, LLMProvider, } from "@arizeai/openinference-semantic-conventions";
112
- import { assertUnreachable, isString } from "./typeUtils";
5
+ import { assertUnreachable, isString } from "./typeUtils.js";
113
6
  import { isTracingSuppressed } from "@opentelemetry/core";
114
7
  import { OITracer, safelyJSONStringify, } from "@arizeai/openinference-core";
115
- var MODULE_NAME = "openai";
8
+ const MODULE_NAME = "openai";
116
9
  /**
117
10
  * Flag to check if the openai module has been patched
118
11
  * Note: This is a fallback in case the module is made immutable (e.x. Deno, webpack, etc.)
119
12
  */
120
- var _isOpenInferencePatched = false;
13
+ let _isOpenInferencePatched = false;
121
14
  /**
122
15
  * function to check if instrumentation is enabled / disabled
123
16
  */
@@ -130,9 +23,9 @@ export function isPatched() {
130
23
  * @param span
131
24
  */
132
25
  function getExecContext(span) {
133
- var activeContext = context.active();
134
- var suppressTracing = isTracingSuppressed(activeContext);
135
- var execContext = suppressTracing
26
+ const activeContext = context.active();
27
+ const suppressTracing = isTracingSuppressed(activeContext);
28
+ const execContext = suppressTracing
136
29
  ? trace.setSpan(context.active(), span)
137
30
  : activeContext;
138
31
  // Drop the span from the context
@@ -146,59 +39,60 @@ function getExecContext(span) {
146
39
  * @param instrumentationConfig The config for the instrumentation @see {@link InstrumentationConfig}
147
40
  * @param traceConfig The OpenInference trace configuration. Can be used to mask or redact sensitive information on spans. @see {@link TraceConfigOptions}
148
41
  */
149
- var OpenAIInstrumentation = /** @class */ (function (_super) {
150
- __extends(OpenAIInstrumentation, _super);
151
- function OpenAIInstrumentation(_a) {
152
- var _b = _a === void 0 ? {} : _a, instrumentationConfig = _b.instrumentationConfig, traceConfig = _b.traceConfig;
153
- var _this = _super.call(this, "@arizeai/openinference-instrumentation-openai", VERSION, Object.assign({}, instrumentationConfig)) || this;
154
- _this.oiTracer = new OITracer({ tracer: _this.tracer, traceConfig: traceConfig });
155
- return _this;
42
+ export class OpenAIInstrumentation extends InstrumentationBase {
43
+ constructor({ instrumentationConfig, traceConfig, } = {}) {
44
+ super("@arizeai/openinference-instrumentation-openai", VERSION, Object.assign({}, instrumentationConfig));
45
+ this.oiTracer = new OITracer({ tracer: this.tracer, traceConfig });
156
46
  }
157
- OpenAIInstrumentation.prototype.init = function () {
158
- var module = new InstrumentationNodeModuleDefinition("openai", ["^4.0.0"], this.patch.bind(this), this.unpatch.bind(this));
47
+ init() {
48
+ const module = new InstrumentationNodeModuleDefinition("openai", ["^4.0.0"], this.patch.bind(this), this.unpatch.bind(this));
159
49
  return module;
160
- };
50
+ }
161
51
  /**
162
52
  * Manually instruments the OpenAI module. This is needed when the module is not loaded via require (commonjs)
163
53
  * @param {openai} module
164
54
  */
165
- OpenAIInstrumentation.prototype.manuallyInstrument = function (module) {
166
- diag.debug("Manually instrumenting ".concat(MODULE_NAME));
55
+ manuallyInstrument(module) {
56
+ diag.debug(`Manually instrumenting ${MODULE_NAME}`);
167
57
  this.patch(module);
168
- };
58
+ }
169
59
  /**
170
60
  * Patches the OpenAI module
171
61
  */
172
- OpenAIInstrumentation.prototype.patch = function (module, moduleVersion) {
173
- diag.debug("Applying patch for ".concat(MODULE_NAME, "@").concat(moduleVersion));
174
- if ((module === null || module === void 0 ? void 0 : module.openInferencePatched) || _isOpenInferencePatched) {
62
+ patch(module, moduleVersion) {
63
+ diag.debug(`Applying patch for ${MODULE_NAME}@${moduleVersion}`);
64
+ if (module?.openInferencePatched || _isOpenInferencePatched) {
175
65
  return module;
176
66
  }
177
67
  // eslint-disable-next-line @typescript-eslint/no-this-alias
178
- var instrumentation = this;
68
+ const instrumentation = this;
179
69
  // Patch create chat completions
180
70
  this._wrap(module.OpenAI.Chat.Completions.prototype, "create",
181
71
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
182
- function (original) {
183
- return function patchedCreate() {
184
- var _a;
185
- var _this = this;
186
- var args = [];
187
- for (var _i = 0; _i < arguments.length; _i++) {
188
- args[_i] = arguments[_i];
189
- }
190
- var body = args[0];
191
- var _messages = body.messages, invocationParameters = __rest(body, ["messages"]);
192
- var span = instrumentation.oiTracer.startSpan("OpenAI Chat Completions", {
72
+ (original) => {
73
+ return function patchedCreate(...args) {
74
+ const body = args[0];
75
+ const { messages: _messages, ...invocationParameters } = body;
76
+ const span = instrumentation.oiTracer.startSpan(`OpenAI Chat Completions`, {
193
77
  kind: SpanKind.INTERNAL,
194
- attributes: __assign(__assign((_a = {}, _a[SemanticConventions.OPENINFERENCE_SPAN_KIND] = OpenInferenceSpanKind.LLM, _a[SemanticConventions.LLM_MODEL_NAME] = body.model, _a[SemanticConventions.INPUT_VALUE] = JSON.stringify(body), _a[SemanticConventions.INPUT_MIME_TYPE] = MimeType.JSON, _a[SemanticConventions.LLM_INVOCATION_PARAMETERS] = JSON.stringify(invocationParameters), _a[SemanticConventions.LLM_SYSTEM] = LLMSystem.OPENAI, _a[SemanticConventions.LLM_PROVIDER] = LLMProvider.OPENAI, _a), getLLMInputMessagesAttributes(body)), getLLMToolsJSONSchema(body)),
78
+ attributes: {
79
+ [SemanticConventions.OPENINFERENCE_SPAN_KIND]: OpenInferenceSpanKind.LLM,
80
+ [SemanticConventions.LLM_MODEL_NAME]: body.model,
81
+ [SemanticConventions.INPUT_VALUE]: JSON.stringify(body),
82
+ [SemanticConventions.INPUT_MIME_TYPE]: MimeType.JSON,
83
+ [SemanticConventions.LLM_INVOCATION_PARAMETERS]: JSON.stringify(invocationParameters),
84
+ [SemanticConventions.LLM_SYSTEM]: LLMSystem.OPENAI,
85
+ [SemanticConventions.LLM_PROVIDER]: LLMProvider.OPENAI,
86
+ ...getLLMInputMessagesAttributes(body),
87
+ ...getLLMToolsJSONSchema(body),
88
+ },
195
89
  });
196
- var execContext = getExecContext(span);
197
- var execPromise = safeExecuteInTheMiddle(function () {
198
- return context.with(trace.setSpan(execContext, span), function () {
199
- return original.apply(_this, args);
90
+ const execContext = getExecContext(span);
91
+ const execPromise = safeExecuteInTheMiddle(() => {
92
+ return context.with(trace.setSpan(execContext, span), () => {
93
+ return original.apply(this, args);
200
94
  });
201
- }, function (error) {
95
+ }, (error) => {
202
96
  // Push the error to the span
203
97
  if (error) {
204
98
  span.recordException(error);
@@ -209,11 +103,17 @@ var OpenAIInstrumentation = /** @class */ (function (_super) {
209
103
  span.end();
210
104
  }
211
105
  });
212
- var wrappedPromise = execPromise.then(function (result) {
213
- var _a;
106
+ const wrappedPromise = execPromise.then((result) => {
214
107
  if (isChatCompletionResponse(result)) {
215
108
  // Record the results
216
- span.setAttributes(__assign(__assign((_a = {}, _a[SemanticConventions.OUTPUT_VALUE] = JSON.stringify(result), _a[SemanticConventions.OUTPUT_MIME_TYPE] = MimeType.JSON, _a[SemanticConventions.LLM_MODEL_NAME] = result.model, _a), getChatCompletionLLMOutputMessagesAttributes(result)), getUsageAttributes(result)));
109
+ span.setAttributes({
110
+ [SemanticConventions.OUTPUT_VALUE]: JSON.stringify(result),
111
+ [SemanticConventions.OUTPUT_MIME_TYPE]: MimeType.JSON,
112
+ // Override the model from the value sent by the server
113
+ [SemanticConventions.LLM_MODEL_NAME]: result.model,
114
+ ...getChatCompletionLLMOutputMessagesAttributes(result),
115
+ ...getUsageAttributes(result),
116
+ });
217
117
  span.setStatus({ code: SpanStatusCode.OK });
218
118
  span.end();
219
119
  }
@@ -221,7 +121,7 @@ var OpenAIInstrumentation = /** @class */ (function (_super) {
221
121
  // This is a streaming response
222
122
  // handle the chunks and add them to the span
223
123
  // First split the stream via tee
224
- var _b = __read(result.tee(), 2), leftStream = _b[0], rightStream = _b[1];
124
+ const [leftStream, rightStream] = result.tee();
225
125
  consumeChatCompletionStreamChunks(rightStream, span);
226
126
  result = leftStream;
227
127
  }
@@ -232,26 +132,27 @@ var OpenAIInstrumentation = /** @class */ (function (_super) {
232
132
  });
233
133
  this._wrap(module.OpenAI.Completions.prototype, "create",
234
134
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
235
- function (original) {
236
- return function patchedCreate() {
237
- var _a;
238
- var _this = this;
239
- var args = [];
240
- for (var _i = 0; _i < arguments.length; _i++) {
241
- args[_i] = arguments[_i];
242
- }
243
- var body = args[0];
244
- var _prompt = body.prompt, invocationParameters = __rest(body, ["prompt"]);
245
- var span = instrumentation.oiTracer.startSpan("OpenAI Completions", {
135
+ (original) => {
136
+ return function patchedCreate(...args) {
137
+ const body = args[0];
138
+ const { prompt: _prompt, ...invocationParameters } = body;
139
+ const span = instrumentation.oiTracer.startSpan(`OpenAI Completions`, {
246
140
  kind: SpanKind.INTERNAL,
247
- attributes: __assign((_a = {}, _a[SemanticConventions.OPENINFERENCE_SPAN_KIND] = OpenInferenceSpanKind.LLM, _a[SemanticConventions.LLM_MODEL_NAME] = body.model, _a[SemanticConventions.LLM_INVOCATION_PARAMETERS] = JSON.stringify(invocationParameters), _a[SemanticConventions.LLM_SYSTEM] = LLMSystem.OPENAI, _a[SemanticConventions.LLM_PROVIDER] = LLMProvider.OPENAI, _a), getCompletionInputValueAndMimeType(body)),
141
+ attributes: {
142
+ [SemanticConventions.OPENINFERENCE_SPAN_KIND]: OpenInferenceSpanKind.LLM,
143
+ [SemanticConventions.LLM_MODEL_NAME]: body.model,
144
+ [SemanticConventions.LLM_INVOCATION_PARAMETERS]: JSON.stringify(invocationParameters),
145
+ [SemanticConventions.LLM_SYSTEM]: LLMSystem.OPENAI,
146
+ [SemanticConventions.LLM_PROVIDER]: LLMProvider.OPENAI,
147
+ ...getCompletionInputValueAndMimeType(body),
148
+ },
248
149
  });
249
- var execContext = getExecContext(span);
250
- var execPromise = safeExecuteInTheMiddle(function () {
251
- return context.with(trace.setSpan(execContext, span), function () {
252
- return original.apply(_this, args);
150
+ const execContext = getExecContext(span);
151
+ const execPromise = safeExecuteInTheMiddle(() => {
152
+ return context.with(trace.setSpan(execContext, span), () => {
153
+ return original.apply(this, args);
253
154
  });
254
- }, function (error) {
155
+ }, (error) => {
255
156
  // Push the error to the span
256
157
  if (error) {
257
158
  span.recordException(error);
@@ -262,11 +163,17 @@ var OpenAIInstrumentation = /** @class */ (function (_super) {
262
163
  span.end();
263
164
  }
264
165
  });
265
- var wrappedPromise = execPromise.then(function (result) {
266
- var _a;
166
+ const wrappedPromise = execPromise.then((result) => {
267
167
  if (isCompletionResponse(result)) {
268
168
  // Record the results
269
- span.setAttributes(__assign(__assign((_a = {}, _a[SemanticConventions.OUTPUT_VALUE] = JSON.stringify(result), _a[SemanticConventions.OUTPUT_MIME_TYPE] = MimeType.JSON, _a[SemanticConventions.LLM_MODEL_NAME] = result.model, _a), getCompletionOutputValueAndMimeType(result)), getUsageAttributes(result)));
169
+ span.setAttributes({
170
+ [SemanticConventions.OUTPUT_VALUE]: JSON.stringify(result),
171
+ [SemanticConventions.OUTPUT_MIME_TYPE]: MimeType.JSON,
172
+ // Override the model from the value sent by the server
173
+ [SemanticConventions.LLM_MODEL_NAME]: result.model,
174
+ ...getCompletionOutputValueAndMimeType(result),
175
+ ...getUsageAttributes(result),
176
+ });
270
177
  span.setStatus({ code: SpanStatusCode.OK });
271
178
  span.end();
272
179
  }
@@ -277,31 +184,31 @@ var OpenAIInstrumentation = /** @class */ (function (_super) {
277
184
  });
278
185
  this._wrap(module.OpenAI.Embeddings.prototype, "create",
279
186
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
280
- function (original) {
281
- return function patchedEmbeddingCreate() {
282
- var _a;
283
- var _this = this;
284
- var args = [];
285
- for (var _i = 0; _i < arguments.length; _i++) {
286
- args[_i] = arguments[_i];
287
- }
288
- var body = args[0];
289
- var input = body.input;
290
- var isStringInput = typeof input === "string";
291
- var span = instrumentation.oiTracer.startSpan("OpenAI Embeddings", {
187
+ (original) => {
188
+ return function patchedEmbeddingCreate(...args) {
189
+ const body = args[0];
190
+ const { input } = body;
191
+ const isStringInput = typeof input === "string";
192
+ const span = instrumentation.oiTracer.startSpan(`OpenAI Embeddings`, {
292
193
  kind: SpanKind.INTERNAL,
293
- attributes: __assign((_a = {}, _a[SemanticConventions.OPENINFERENCE_SPAN_KIND] = OpenInferenceSpanKind.EMBEDDING, _a[SemanticConventions.EMBEDDING_MODEL_NAME] = body.model, _a[SemanticConventions.INPUT_VALUE] = isStringInput
294
- ? input
295
- : JSON.stringify(input), _a[SemanticConventions.INPUT_MIME_TYPE] = isStringInput
296
- ? MimeType.TEXT
297
- : MimeType.JSON, _a), getEmbeddingTextAttributes(body)),
194
+ attributes: {
195
+ [SemanticConventions.OPENINFERENCE_SPAN_KIND]: OpenInferenceSpanKind.EMBEDDING,
196
+ [SemanticConventions.EMBEDDING_MODEL_NAME]: body.model,
197
+ [SemanticConventions.INPUT_VALUE]: isStringInput
198
+ ? input
199
+ : JSON.stringify(input),
200
+ [SemanticConventions.INPUT_MIME_TYPE]: isStringInput
201
+ ? MimeType.TEXT
202
+ : MimeType.JSON,
203
+ ...getEmbeddingTextAttributes(body),
204
+ },
298
205
  });
299
- var execContext = getExecContext(span);
300
- var execPromise = safeExecuteInTheMiddle(function () {
301
- return context.with(trace.setSpan(execContext, span), function () {
302
- return original.apply(_this, args);
206
+ const execContext = getExecContext(span);
207
+ const execPromise = safeExecuteInTheMiddle(() => {
208
+ return context.with(trace.setSpan(execContext, span), () => {
209
+ return original.apply(this, args);
303
210
  });
304
- }, function (error) {
211
+ }, (error) => {
305
212
  // Push the error to the span
306
213
  if (error) {
307
214
  span.recordException(error);
@@ -312,10 +219,13 @@ var OpenAIInstrumentation = /** @class */ (function (_super) {
312
219
  span.end();
313
220
  }
314
221
  });
315
- var wrappedPromise = execPromise.then(function (result) {
222
+ const wrappedPromise = execPromise.then((result) => {
316
223
  if (result) {
317
224
  // Record the results
318
- span.setAttributes(__assign({}, getEmbeddingEmbeddingsAttributes(result)));
225
+ span.setAttributes({
226
+ // Do not record the output data as it can be large
227
+ ...getEmbeddingEmbeddingsAttributes(result),
228
+ });
319
229
  }
320
230
  span.setStatus({ code: SpanStatusCode.OK });
321
231
  span.end();
@@ -330,15 +240,15 @@ var OpenAIInstrumentation = /** @class */ (function (_super) {
330
240
  module.openInferencePatched = true;
331
241
  }
332
242
  catch (e) {
333
- diag.debug("Failed to set ".concat(MODULE_NAME, " patched flag on the module"), e);
243
+ diag.debug(`Failed to set ${MODULE_NAME} patched flag on the module`, e);
334
244
  }
335
245
  return module;
336
- };
246
+ }
337
247
  /**
338
248
  * Un-patches the OpenAI module's chat completions API
339
249
  */
340
- OpenAIInstrumentation.prototype.unpatch = function (moduleExports, moduleVersion) {
341
- diag.debug("Removing patch for ".concat(MODULE_NAME, "@").concat(moduleVersion));
250
+ unpatch(moduleExports, moduleVersion) {
251
+ diag.debug(`Removing patch for ${MODULE_NAME}@${moduleVersion}`);
342
252
  this._unwrap(moduleExports.OpenAI.Chat.Completions.prototype, "create");
343
253
  this._unwrap(moduleExports.OpenAI.Completions.prototype, "create");
344
254
  this._unwrap(moduleExports.OpenAI.Embeddings.prototype, "create");
@@ -348,12 +258,10 @@ var OpenAIInstrumentation = /** @class */ (function (_super) {
348
258
  moduleExports.openInferencePatched = false;
349
259
  }
350
260
  catch (e) {
351
- diag.warn("Failed to unset ".concat(MODULE_NAME, " patched flag on the module"), e);
261
+ diag.warn(`Failed to unset ${MODULE_NAME} patched flag on the module`, e);
352
262
  }
353
- };
354
- return OpenAIInstrumentation;
355
- }(InstrumentationBase));
356
- export { OpenAIInstrumentation };
263
+ }
264
+ }
357
265
  /**
358
266
  * type-guard that checks if the response is a chat completion response
359
267
  */
@@ -370,29 +278,18 @@ function isCompletionResponse(response) {
370
278
  * type-guard that checks if completion prompt attribute is an array of strings
371
279
  */
372
280
  function isPromptStringArray(prompt) {
373
- return (Array.isArray(prompt) && prompt.every(function (item) { return typeof item === "string"; }));
281
+ return (Array.isArray(prompt) && prompt.every((item) => typeof item === "string"));
374
282
  }
375
283
  /**
376
284
  * Converts the body of a chat completions request to LLM input messages
377
285
  */
378
286
  function getLLMInputMessagesAttributes(body) {
379
- return body.messages.reduce(function (acc, message, index) {
380
- var e_1, _a;
381
- var messageAttributes = getChatCompletionInputMessageAttributes(message);
382
- var indexPrefix = "".concat(SemanticConventions.LLM_INPUT_MESSAGES, ".").concat(index, ".");
383
- try {
384
- // Flatten the attributes on the index prefix
385
- for (var _b = __values(Object.entries(messageAttributes)), _c = _b.next(); !_c.done; _c = _b.next()) {
386
- var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
387
- acc["".concat(indexPrefix).concat(key)] = value;
388
- }
389
- }
390
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
391
- finally {
392
- try {
393
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
394
- }
395
- finally { if (e_1) throw e_1.error; }
287
+ return body.messages.reduce((acc, message, index) => {
288
+ const messageAttributes = getChatCompletionInputMessageAttributes(message);
289
+ const indexPrefix = `${SemanticConventions.LLM_INPUT_MESSAGES}.${index}.`;
290
+ // Flatten the attributes on the index prefix
291
+ for (const [key, value] of Object.entries(messageAttributes)) {
292
+ acc[`${indexPrefix}${key}`] = value;
396
293
  }
397
294
  return acc;
398
295
  }, {});
@@ -405,9 +302,9 @@ function getLLMToolsJSONSchema(body) {
405
302
  // If tools is undefined, return an empty object
406
303
  return {};
407
304
  }
408
- return body.tools.reduce(function (acc, tool, index) {
409
- var toolJsonSchema = safelyJSONStringify(tool);
410
- var key = "".concat(SemanticConventions.LLM_TOOLS, ".").concat(index, ".").concat(SemanticConventions.TOOL_JSON_SCHEMA);
305
+ return body.tools.reduce((acc, tool, index) => {
306
+ const toolJsonSchema = safelyJSONStringify(tool);
307
+ const key = `${SemanticConventions.LLM_TOOLS}.${index}.${SemanticConventions.TOOL_JSON_SCHEMA}`;
411
308
  if (toolJsonSchema) {
412
309
  acc[key] = toolJsonSchema;
413
310
  }
@@ -415,25 +312,24 @@ function getLLMToolsJSONSchema(body) {
415
312
  }, {});
416
313
  }
417
314
  function getChatCompletionInputMessageAttributes(message) {
418
- var _a;
419
- var role = message.role;
420
- var attributes = (_a = {},
421
- _a[SemanticConventions.MESSAGE_ROLE] = role,
422
- _a);
315
+ const role = message.role;
316
+ const attributes = {
317
+ [SemanticConventions.MESSAGE_ROLE]: role,
318
+ };
423
319
  // Add the content only if it is a string
424
320
  if (typeof message.content === "string") {
425
321
  attributes[SemanticConventions.MESSAGE_CONTENT] = message.content;
426
322
  }
427
323
  else if (Array.isArray(message.content)) {
428
- message.content.forEach(function (part, index) {
429
- var contentsIndexPrefix = "".concat(SemanticConventions.MESSAGE_CONTENTS, ".").concat(index, ".");
324
+ message.content.forEach((part, index) => {
325
+ const contentsIndexPrefix = `${SemanticConventions.MESSAGE_CONTENTS}.${index}.`;
430
326
  if (part.type === "text") {
431
- attributes["".concat(contentsIndexPrefix).concat(SemanticConventions.MESSAGE_CONTENT_TYPE)] = "text";
432
- attributes["".concat(contentsIndexPrefix).concat(SemanticConventions.MESSAGE_CONTENT_TEXT)] = part.text;
327
+ attributes[`${contentsIndexPrefix}${SemanticConventions.MESSAGE_CONTENT_TYPE}`] = "text";
328
+ attributes[`${contentsIndexPrefix}${SemanticConventions.MESSAGE_CONTENT_TEXT}`] = part.text;
433
329
  }
434
330
  else if (part.type === "image_url") {
435
- attributes["".concat(contentsIndexPrefix).concat(SemanticConventions.MESSAGE_CONTENT_TYPE)] = "image";
436
- attributes["".concat(contentsIndexPrefix).concat(SemanticConventions.MESSAGE_CONTENT_IMAGE)] = part.image_url.url;
331
+ attributes[`${contentsIndexPrefix}${SemanticConventions.MESSAGE_CONTENT_TYPE}`] = "image";
332
+ attributes[`${contentsIndexPrefix}${SemanticConventions.MESSAGE_CONTENT_IMAGE}`] = part.image_url.url;
437
333
  }
438
334
  });
439
335
  }
@@ -443,16 +339,16 @@ function getChatCompletionInputMessageAttributes(message) {
443
339
  break;
444
340
  case "assistant":
445
341
  if (message.tool_calls) {
446
- message.tool_calls.forEach(function (toolCall, index) {
447
- var toolCallIndexPrefix = "".concat(SemanticConventions.MESSAGE_TOOL_CALLS, ".").concat(index, ".");
342
+ message.tool_calls.forEach((toolCall, index) => {
343
+ const toolCallIndexPrefix = `${SemanticConventions.MESSAGE_TOOL_CALLS}.${index}.`;
448
344
  // Add the tool call id if it exists
449
345
  if (toolCall.id) {
450
- attributes["".concat(toolCallIndexPrefix).concat(SemanticConventions.TOOL_CALL_ID)] = toolCall.id;
346
+ attributes[`${toolCallIndexPrefix}${SemanticConventions.TOOL_CALL_ID}`] = toolCall.id;
451
347
  }
452
348
  // Make sure the tool call has a function
453
349
  if (toolCall.function) {
454
- attributes["".concat(toolCallIndexPrefix).concat(SemanticConventions.TOOL_CALL_FUNCTION_NAME)] = toolCall.function.name;
455
- attributes["".concat(toolCallIndexPrefix).concat(SemanticConventions.TOOL_CALL_FUNCTION_ARGUMENTS_JSON)] = toolCall.function.arguments;
350
+ attributes[`${toolCallIndexPrefix}${SemanticConventions.TOOL_CALL_FUNCTION_NAME}`] = toolCall.function.name;
351
+ attributes[`${toolCallIndexPrefix}${SemanticConventions.TOOL_CALL_FUNCTION_ARGUMENTS_JSON}`] = toolCall.function.arguments;
456
352
  }
457
353
  });
458
354
  }
@@ -462,7 +358,7 @@ function getChatCompletionInputMessageAttributes(message) {
462
358
  break;
463
359
  case "tool":
464
360
  if (message.tool_call_id) {
465
- attributes["".concat(SemanticConventions.MESSAGE_TOOL_CALL_ID)] =
361
+ attributes[`${SemanticConventions.MESSAGE_TOOL_CALL_ID}`] =
466
362
  message.tool_call_id;
467
363
  }
468
364
  break;
@@ -479,22 +375,21 @@ function getChatCompletionInputMessageAttributes(message) {
479
375
  * Converts the body of a completions request to input attributes
480
376
  */
481
377
  function getCompletionInputValueAndMimeType(body) {
482
- var _a, _b;
483
378
  if (typeof body.prompt === "string") {
484
- return _a = {},
485
- _a[SemanticConventions.INPUT_VALUE] = body.prompt,
486
- _a[SemanticConventions.INPUT_MIME_TYPE] = MimeType.TEXT,
487
- _a;
379
+ return {
380
+ [SemanticConventions.INPUT_VALUE]: body.prompt,
381
+ [SemanticConventions.INPUT_MIME_TYPE]: MimeType.TEXT,
382
+ };
488
383
  }
489
384
  else if (isPromptStringArray(body.prompt)) {
490
- var prompt = body.prompt[0]; // Only single prompts are currently supported
385
+ const prompt = body.prompt[0]; // Only single prompts are currently supported
491
386
  if (prompt === undefined) {
492
387
  return {};
493
388
  }
494
- return _b = {},
495
- _b[SemanticConventions.INPUT_VALUE] = prompt,
496
- _b[SemanticConventions.INPUT_MIME_TYPE] = MimeType.TEXT,
497
- _b;
389
+ return {
390
+ [SemanticConventions.INPUT_VALUE]: prompt,
391
+ [SemanticConventions.INPUT_MIME_TYPE]: MimeType.TEXT,
392
+ };
498
393
  }
499
394
  // Other cases in which the prompt is a token or array of tokens are currently unsupported
500
395
  return {};
@@ -503,13 +398,12 @@ function getCompletionInputValueAndMimeType(body) {
503
398
  * Get usage attributes
504
399
  */
505
400
  function getUsageAttributes(completion) {
506
- var _a;
507
401
  if (completion.usage) {
508
- return _a = {},
509
- _a[SemanticConventions.LLM_TOKEN_COUNT_COMPLETION] = completion.usage.completion_tokens,
510
- _a[SemanticConventions.LLM_TOKEN_COUNT_PROMPT] = completion.usage.prompt_tokens,
511
- _a[SemanticConventions.LLM_TOKEN_COUNT_TOTAL] = completion.usage.total_tokens,
512
- _a;
402
+ return {
403
+ [SemanticConventions.LLM_TOKEN_COUNT_COMPLETION]: completion.usage.completion_tokens,
404
+ [SemanticConventions.LLM_TOKEN_COUNT_PROMPT]: completion.usage.prompt_tokens,
405
+ [SemanticConventions.LLM_TOKEN_COUNT_TOTAL]: completion.usage.total_tokens,
406
+ };
513
407
  }
514
408
  return {};
515
409
  }
@@ -518,46 +412,34 @@ function getUsageAttributes(completion) {
518
412
  */
519
413
  function getChatCompletionLLMOutputMessagesAttributes(chatCompletion) {
520
414
  // Right now support just the first choice
521
- var choice = chatCompletion.choices[0];
415
+ const choice = chatCompletion.choices[0];
522
416
  if (!choice) {
523
417
  return {};
524
418
  }
525
- return [choice.message].reduce(function (acc, message, index) {
526
- var e_2, _a;
527
- var indexPrefix = "".concat(SemanticConventions.LLM_OUTPUT_MESSAGES, ".").concat(index, ".");
528
- var messageAttributes = getChatCompletionOutputMessageAttributes(message);
529
- try {
530
- // Flatten the attributes on the index prefix
531
- for (var _b = __values(Object.entries(messageAttributes)), _c = _b.next(); !_c.done; _c = _b.next()) {
532
- var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
533
- acc["".concat(indexPrefix).concat(key)] = value;
534
- }
535
- }
536
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
537
- finally {
538
- try {
539
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
540
- }
541
- finally { if (e_2) throw e_2.error; }
419
+ return [choice.message].reduce((acc, message, index) => {
420
+ const indexPrefix = `${SemanticConventions.LLM_OUTPUT_MESSAGES}.${index}.`;
421
+ const messageAttributes = getChatCompletionOutputMessageAttributes(message);
422
+ // Flatten the attributes on the index prefix
423
+ for (const [key, value] of Object.entries(messageAttributes)) {
424
+ acc[`${indexPrefix}${key}`] = value;
542
425
  }
543
426
  return acc;
544
427
  }, {});
545
428
  }
546
429
  function getChatCompletionOutputMessageAttributes(message) {
547
- var _a;
548
- var role = message.role;
549
- var attributes = (_a = {},
550
- _a[SemanticConventions.MESSAGE_ROLE] = role,
551
- _a);
430
+ const role = message.role;
431
+ const attributes = {
432
+ [SemanticConventions.MESSAGE_ROLE]: role,
433
+ };
552
434
  if (message.content) {
553
435
  attributes[SemanticConventions.MESSAGE_CONTENT] = message.content;
554
436
  }
555
437
  if (message.tool_calls) {
556
- message.tool_calls.forEach(function (toolCall, index) {
557
- var toolCallIndexPrefix = "".concat(SemanticConventions.MESSAGE_TOOL_CALLS, ".").concat(index, ".");
438
+ message.tool_calls.forEach((toolCall, index) => {
439
+ const toolCallIndexPrefix = `${SemanticConventions.MESSAGE_TOOL_CALLS}.${index}.`;
558
440
  // Add the tool call id if it exists
559
441
  if (toolCall.id) {
560
- attributes["".concat(toolCallIndexPrefix).concat(SemanticConventions.TOOL_CALL_ID)] = toolCall.id;
442
+ attributes[`${toolCallIndexPrefix}${SemanticConventions.TOOL_CALL_ID}`] = toolCall.id;
561
443
  }
562
444
  // Double check that the tool call has a function
563
445
  // NB: OpenAI only supports tool calls with functions right now but this may change
@@ -580,33 +462,31 @@ function getChatCompletionOutputMessageAttributes(message) {
580
462
  * Converts the completion result to output attributes
581
463
  */
582
464
  function getCompletionOutputValueAndMimeType(completion) {
583
- var _a;
584
465
  // Right now support just the first choice
585
- var choice = completion.choices[0];
466
+ const choice = completion.choices[0];
586
467
  if (!choice) {
587
468
  return {};
588
469
  }
589
- return _a = {},
590
- _a[SemanticConventions.OUTPUT_VALUE] = String(choice.text),
591
- _a[SemanticConventions.OUTPUT_MIME_TYPE] = MimeType.TEXT,
592
- _a;
470
+ return {
471
+ [SemanticConventions.OUTPUT_VALUE]: String(choice.text),
472
+ [SemanticConventions.OUTPUT_MIME_TYPE]: MimeType.TEXT,
473
+ };
593
474
  }
594
475
  /**
595
476
  * Converts the embedding result payload to embedding attributes
596
477
  */
597
478
  function getEmbeddingTextAttributes(request) {
598
- var _a;
599
479
  if (typeof request.input === "string") {
600
- return _a = {},
601
- _a["".concat(SemanticConventions.EMBEDDING_EMBEDDINGS, ".0.").concat(SemanticConventions.EMBEDDING_TEXT)] = request.input,
602
- _a;
480
+ return {
481
+ [`${SemanticConventions.EMBEDDING_EMBEDDINGS}.0.${SemanticConventions.EMBEDDING_TEXT}`]: request.input,
482
+ };
603
483
  }
604
484
  else if (Array.isArray(request.input) &&
605
485
  request.input.length > 0 &&
606
486
  typeof request.input[0] === "string") {
607
- return request.input.reduce(function (acc, input, index) {
608
- var indexPrefix = "".concat(SemanticConventions.EMBEDDING_EMBEDDINGS, ".").concat(index, ".");
609
- acc["".concat(indexPrefix).concat(SemanticConventions.EMBEDDING_TEXT)] = input;
487
+ return request.input.reduce((acc, input, index) => {
488
+ const indexPrefix = `${SemanticConventions.EMBEDDING_EMBEDDINGS}.${index}.`;
489
+ acc[`${indexPrefix}${SemanticConventions.EMBEDDING_TEXT}`] = input;
610
490
  return acc;
611
491
  }, {});
612
492
  }
@@ -617,9 +497,9 @@ function getEmbeddingTextAttributes(request) {
617
497
  * Converts the embedding result payload to embedding attributes
618
498
  */
619
499
  function getEmbeddingEmbeddingsAttributes(response) {
620
- return response.data.reduce(function (acc, embedding, index) {
621
- var indexPrefix = "".concat(SemanticConventions.EMBEDDING_EMBEDDINGS, ".").concat(index, ".");
622
- acc["".concat(indexPrefix).concat(SemanticConventions.EMBEDDING_VECTOR)] =
500
+ return response.data.reduce((acc, embedding, index) => {
501
+ const indexPrefix = `${SemanticConventions.EMBEDDING_EMBEDDINGS}.${index}.`;
502
+ acc[`${indexPrefix}${SemanticConventions.EMBEDDING_VECTOR}`] =
623
503
  embedding.embedding;
624
504
  return acc;
625
505
  }, {});
@@ -627,103 +507,47 @@ function getEmbeddingEmbeddingsAttributes(response) {
627
507
  /**
628
508
  * Consumes the stream chunks and adds them to the span
629
509
  */
630
- function consumeChatCompletionStreamChunks(stream, span) {
631
- return __awaiter(this, void 0, void 0, function () {
632
- var streamResponse, toolAndFunctionCallAttributes, chunk, choice, toolAndFunctionCallAttributesDiff, _a, _b, _c, key, value, e_3_1, messageIndexPrefix, attributes, _d, _e, _f, key, value;
633
- var e_4, _g, _h, e_5, _j;
634
- var _k, stream_1, stream_1_1;
635
- var _l, e_3, _m, _o;
636
- return __generator(this, function (_p) {
637
- switch (_p.label) {
638
- case 0:
639
- streamResponse = "";
640
- toolAndFunctionCallAttributes = {};
641
- _p.label = 1;
642
- case 1:
643
- _p.trys.push([1, 6, 7, 12]);
644
- _k = true, stream_1 = __asyncValues(stream);
645
- _p.label = 2;
646
- case 2: return [4 /*yield*/, stream_1.next()];
647
- case 3:
648
- if (!(stream_1_1 = _p.sent(), _l = stream_1_1.done, !_l)) return [3 /*break*/, 5];
649
- _o = stream_1_1.value;
650
- _k = false;
651
- chunk = _o;
652
- if (chunk.choices.length <= 0) {
653
- return [3 /*break*/, 4];
654
- }
655
- choice = chunk.choices[0];
656
- if (choice.delta.content) {
657
- streamResponse += choice.delta.content;
658
- }
659
- toolAndFunctionCallAttributesDiff = getToolAndFunctionCallAttributesFromStreamChunk(chunk);
660
- try {
661
- for (_a = (e_4 = void 0, __values(Object.entries(toolAndFunctionCallAttributesDiff))), _b = _a.next(); !_b.done; _b = _a.next()) {
662
- _c = __read(_b.value, 2), key = _c[0], value = _c[1];
663
- if (isString(toolAndFunctionCallAttributes[key]) && isString(value)) {
664
- toolAndFunctionCallAttributes[key] += value;
665
- }
666
- else if (isString(value)) {
667
- toolAndFunctionCallAttributes[key] = value;
668
- }
669
- }
670
- }
671
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
672
- finally {
673
- try {
674
- if (_b && !_b.done && (_g = _a.return)) _g.call(_a);
675
- }
676
- finally { if (e_4) throw e_4.error; }
677
- }
678
- _p.label = 4;
679
- case 4:
680
- _k = true;
681
- return [3 /*break*/, 2];
682
- case 5: return [3 /*break*/, 12];
683
- case 6:
684
- e_3_1 = _p.sent();
685
- e_3 = { error: e_3_1 };
686
- return [3 /*break*/, 12];
687
- case 7:
688
- _p.trys.push([7, , 10, 11]);
689
- if (!(!_k && !_l && (_m = stream_1.return))) return [3 /*break*/, 9];
690
- return [4 /*yield*/, _m.call(stream_1)];
691
- case 8:
692
- _p.sent();
693
- _p.label = 9;
694
- case 9: return [3 /*break*/, 11];
695
- case 10:
696
- if (e_3) throw e_3.error;
697
- return [7 /*endfinally*/];
698
- case 11: return [7 /*endfinally*/];
699
- case 12:
700
- messageIndexPrefix = "".concat(SemanticConventions.LLM_OUTPUT_MESSAGES, ".0.");
701
- attributes = (_h = {},
702
- _h[SemanticConventions.OUTPUT_VALUE] = streamResponse,
703
- _h[SemanticConventions.OUTPUT_MIME_TYPE] = MimeType.TEXT,
704
- _h["".concat(messageIndexPrefix).concat(SemanticConventions.MESSAGE_CONTENT)] = streamResponse,
705
- _h["".concat(messageIndexPrefix).concat(SemanticConventions.MESSAGE_ROLE)] = "assistant",
706
- _h);
707
- try {
708
- // Add the tool and function call attributes
709
- for (_d = __values(Object.entries(toolAndFunctionCallAttributes)), _e = _d.next(); !_e.done; _e = _d.next()) {
710
- _f = __read(_e.value, 2), key = _f[0], value = _f[1];
711
- attributes["".concat(messageIndexPrefix).concat(key)] = value;
712
- }
713
- }
714
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
715
- finally {
716
- try {
717
- if (_e && !_e.done && (_j = _d.return)) _j.call(_d);
718
- }
719
- finally { if (e_5) throw e_5.error; }
720
- }
721
- span.setAttributes(attributes);
722
- span.end();
723
- return [2 /*return*/];
510
+ async function consumeChatCompletionStreamChunks(stream, span) {
511
+ let streamResponse = "";
512
+ // Tool and function call attributes can also arrive in the stream
513
+ // NB: the tools and function calls arrive in partial diffs
514
+ // So the final tool and function calls need to be aggregated
515
+ // across chunks
516
+ const toolAndFunctionCallAttributes = {};
517
+ // The first message is for the assistant response so we start at 1
518
+ for await (const chunk of stream) {
519
+ if (chunk.choices.length <= 0) {
520
+ continue;
521
+ }
522
+ const choice = chunk.choices[0];
523
+ if (choice.delta.content) {
524
+ streamResponse += choice.delta.content;
525
+ }
526
+ // Accumulate the tool and function call attributes
527
+ const toolAndFunctionCallAttributesDiff = getToolAndFunctionCallAttributesFromStreamChunk(chunk);
528
+ for (const [key, value] of Object.entries(toolAndFunctionCallAttributesDiff)) {
529
+ if (isString(toolAndFunctionCallAttributes[key]) && isString(value)) {
530
+ toolAndFunctionCallAttributes[key] += value;
724
531
  }
725
- });
726
- });
532
+ else if (isString(value)) {
533
+ toolAndFunctionCallAttributes[key] = value;
534
+ }
535
+ }
536
+ }
537
+ const messageIndexPrefix = `${SemanticConventions.LLM_OUTPUT_MESSAGES}.0.`;
538
+ // Append the attributes to the span as a message
539
+ const attributes = {
540
+ [SemanticConventions.OUTPUT_VALUE]: streamResponse,
541
+ [SemanticConventions.OUTPUT_MIME_TYPE]: MimeType.TEXT,
542
+ [`${messageIndexPrefix}${SemanticConventions.MESSAGE_CONTENT}`]: streamResponse,
543
+ [`${messageIndexPrefix}${SemanticConventions.MESSAGE_ROLE}`]: "assistant",
544
+ };
545
+ // Add the tool and function call attributes
546
+ for (const [key, value] of Object.entries(toolAndFunctionCallAttributes)) {
547
+ attributes[`${messageIndexPrefix}${key}`] = value;
548
+ }
549
+ span.setAttributes(attributes);
550
+ span.end();
727
551
  }
728
552
  /**
729
553
  * Extracts the semantic attributes from the stream chunk for tool_calls and function_calls
@@ -732,14 +556,14 @@ function getToolAndFunctionCallAttributesFromStreamChunk(chunk) {
732
556
  if (chunk.choices.length <= 0) {
733
557
  return {};
734
558
  }
735
- var choice = chunk.choices[0];
736
- var attributes = {};
559
+ const choice = chunk.choices[0];
560
+ const attributes = {};
737
561
  if (choice.delta.tool_calls) {
738
- choice.delta.tool_calls.forEach(function (toolCall, index) {
739
- var toolCallIndexPrefix = "".concat(SemanticConventions.MESSAGE_TOOL_CALLS, ".").concat(index, ".");
562
+ choice.delta.tool_calls.forEach((toolCall, index) => {
563
+ const toolCallIndexPrefix = `${SemanticConventions.MESSAGE_TOOL_CALLS}.${index}.`;
740
564
  // Add the tool call id if it exists
741
565
  if (toolCall.id) {
742
- attributes["".concat(toolCallIndexPrefix).concat(SemanticConventions.TOOL_CALL_ID)] = toolCall.id;
566
+ attributes[`${toolCallIndexPrefix}${SemanticConventions.TOOL_CALL_ID}`] = toolCall.id;
743
567
  }
744
568
  // Double check that the tool call has a function
745
569
  // NB: OpenAI only supports tool calls with functions right now but this may change