|
| 1 | +import OpenAI from 'openai'; |
| 2 | +import { Stream } from 'openai/src/streaming'; |
| 3 | +import { addChatCompletionStepToTrace } from '../tracing/tracer'; |
| 4 | + |
| 5 | +export function traceOpenAI(openai: OpenAI): OpenAI { |
| 6 | + const createFunction = openai.chat.completions.create; |
| 7 | + |
| 8 | + openai.chat.completions.create = async function ( |
| 9 | + this: typeof openai.chat.completions, |
| 10 | + ...args: Parameters<typeof createFunction> |
| 11 | + ): Promise<Stream<OpenAI.Chat.Completions.ChatCompletionChunk> | OpenAI.Chat.Completions.ChatCompletion> { |
| 12 | + const [params, options = { stream: false }] = args; |
| 13 | + try { |
| 14 | + const startTime = performance.now(); |
| 15 | + if (options.stream) { |
| 16 | + console.log('streaming not implemented yet'); |
| 17 | + return createFunction.apply(this, args) as unknown as Promise< |
| 18 | + Stream<OpenAI.Chat.Completions.ChatCompletionChunk> |
| 19 | + >; |
| 20 | + } else { |
| 21 | + const response = (await createFunction.apply(this, args)) as OpenAI.Chat.Completions.ChatCompletion; |
| 22 | + const completion = response.choices[0]; |
| 23 | + const endTime = performance.now(); |
| 24 | + const traceData = { |
| 25 | + name: 'OpenAI Chat Completion', |
| 26 | + inputs: { prompt: params.messages }, |
| 27 | + output: completion?.message.content, |
| 28 | + latency: endTime - startTime, |
| 29 | + tokens: response?.usage?.total_tokens ?? null, |
| 30 | + promptTokens: response?.usage?.prompt_tokens ?? null, |
| 31 | + completionTokens: response?.usage?.completion_tokens ?? null, |
| 32 | + model: response?.model, |
| 33 | + modelParameters: getModelParameters(args), |
| 34 | + rawOutput: JSON.stringify(response, null, 2), |
| 35 | + metadata: {}, |
| 36 | + provider: 'OpenAI', |
| 37 | + }; |
| 38 | + addChatCompletionStepToTrace(traceData); |
| 39 | + return response; |
| 40 | + } |
| 41 | + } catch (error) { |
| 42 | + console.error('Failed to trace the create chat completion request with Openlayer', error); |
| 43 | + throw error; |
| 44 | + } |
| 45 | + } as typeof createFunction; |
| 46 | + |
| 47 | + return openai; |
| 48 | +} |
| 49 | + |
| 50 | +function getModelParameters(args: any): Record<string, any> { |
| 51 | + const params = args[0]; |
| 52 | + return { |
| 53 | + frequency_penalty: params?.frequencyPenalty ?? 0, |
| 54 | + logit_bias: params?.logitBias ?? null, |
| 55 | + logprobs: params?.logprobs ?? false, |
| 56 | + top_logprobs: params?.topLogprobs ?? null, |
| 57 | + max_tokens: params?.maxTokens ?? null, |
| 58 | + n: params?.n ?? 1, |
| 59 | + presence_penalty: params?.presencePenalty ?? 0, |
| 60 | + seed: params?.seed ?? null, |
| 61 | + stop: params?.stop ?? null, |
| 62 | + temperature: params?.temperature ?? 1, |
| 63 | + top_p: params?.topP ?? 1, |
| 64 | + }; |
| 65 | +} |
0 commit comments