_getPatchedChatCompletionsCreate()

in packages/instrumentation-openai/src/instrumentation.ts [145:224]


  _getPatchedChatCompletionsCreate() {
    const self = this;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return (original: (...args: unknown[]) => any) => {
      // https://platform.openai.com/docs/api-reference/chat/create
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      return function patchedCreate(this: any, ...args: unknown[]) {
        if (!self.isEnabled) {
          return original.apply(this, args);
        }

        debug('OpenAI.Chat.Completions.create args: %O', args);
        /** type ChatCompletionCreateParamsStreaming */
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const params = args[0] as any;
        const config = self.getConfig();
        const startNow = performance.now();

        let startInfo;
        try {
          startInfo = self._startChatCompletionsSpan(
            params,
            config,
            this?._client?.baseURL
          );
        } catch (err) {
          self._diag.error('unexpected error starting span:', err);
          return original.apply(this, args);
        }
        const { span, ctx, commonAttrs } = startInfo;

        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const apiPromise: Promise<any> = context.with(ctx, () =>
          original.apply(this, args)
        );

        // Streaming.
        if (params && params.stream) {
          // When streaming, `apiPromise` resolves to `import('openai/streaming').Stream`,
          // an async iterable (i.e. has a `Symbol.asyncIterator` method). We
          // want to wrap that iteration to gather telemetry. Instead of wrapping
          // `Symbol.asyncIterator`, which would be nice, we wrap the `iterator`
          // method because it is used internally by `Stream#tee()`.
          return apiPromise.then(stream => {
            self._wrap(stream, 'iterator', origIterator => {
              return () => {
                return self._onChatCompletionsStreamIterator(
                  origIterator(),
                  span,
                  startNow,
                  config,
                  commonAttrs,
                  ctx
                );
              };
            });
            return stream;
          });
        }

        // Non-streaming.
        apiPromise
          .then(result => {
            self._onChatCompletionsCreateResult(
              span,
              startNow,
              commonAttrs,
              result,
              config,
              ctx
            );
          })
          .catch(
            self._createAPIPromiseRejectionHandler(startNow, span, commonAttrs)
          );

        return apiPromise;
      };
    };
  }