@@ -78,27 +78,12 @@ class OpenAiTracingPlugin extends TracingPlugin {
78
78
kind : 'client' ,
79
79
meta : {
80
80
[ MEASURED ] : 1 ,
81
- // Data that is always available with a request
82
- 'openai.user.api_key' : truncateApiKey ( apiKey ) ,
83
- 'openai.api_base' : basePath ,
84
81
// The openai.api_type (openai|azure) is present in Python but not in Node.js
85
82
// Add support once https://github.com/openai/openai-node/issues/53 is closed
86
83
87
84
// Data that is common across many requests
88
- 'openai.request.best_of' : payload . best_of ,
89
- 'openai.request.echo' : payload . echo ,
90
- 'openai.request.logprobs' : payload . logprobs ,
91
- 'openai.request.max_tokens' : payload . max_tokens ,
92
85
'openai.request.model' : payload . model , // vague model
93
- 'openai.request.n' : payload . n ,
94
- 'openai.request.presence_penalty' : payload . presence_penalty ,
95
- 'openai.request.frequency_penalty' : payload . frequency_penalty ,
96
- 'openai.request.stop' : payload . stop ,
97
86
'openai.request.suffix' : payload . suffix ,
98
- 'openai.request.temperature' : payload . temperature ,
99
- 'openai.request.top_p' : payload . top_p ,
100
- 'openai.request.user' : payload . user ,
101
- 'openai.request.file_id' : payload . file_id // deleteFile, retrieveFile, downloadFile
102
87
}
103
88
} , false )
104
89
@@ -110,34 +95,14 @@ class OpenAiTracingPlugin extends TracingPlugin {
110
95
if ( payload . prompt ) {
111
96
const prompt = payload . prompt
112
97
openaiStore . prompt = prompt
113
- if ( typeof prompt === 'string' || ( Array . isArray ( prompt ) && typeof prompt [ 0 ] === 'number' ) ) {
114
- // This is a single prompt, either String or [Number]
115
- tags [ 'openai.request.prompt' ] = normalizeStringOrTokenArray ( prompt , true )
116
- } else if ( Array . isArray ( prompt ) ) {
117
- // This is multiple prompts, either [String] or [[Number]]
118
- for ( let i = 0 ; i < prompt . length ; i ++ ) {
119
- tags [ `openai.request.prompt.${ i } ` ] = normalizeStringOrTokenArray ( prompt [ i ] , true )
120
- }
121
- }
122
98
}
123
99
124
100
// createEdit, createEmbedding, createModeration
125
101
if ( payload . input ) {
126
102
const normalized = normalizeStringOrTokenArray ( payload . input , false )
127
- tags [ 'openai.request.input' ] = normalize ( normalized )
128
103
openaiStore . input = normalized
129
104
}
130
105
131
- // createChatCompletion, createCompletion
132
- if ( payload . logit_bias !== null && typeof payload . logit_bias === 'object' ) {
133
- for ( const [ tokenId , bias ] of Object . entries ( payload . logit_bias ) ) {
134
- tags [ `openai.request.logit_bias.${ tokenId } ` ] = bias
135
- }
136
- }
137
-
138
- if ( payload . stream ) {
139
- tags [ 'openai.request.stream' ] = payload . stream
140
- }
141
106
142
107
switch ( normalizedMethodName ) {
143
108
case 'createFineTune' :
@@ -230,17 +195,8 @@ class OpenAiTracingPlugin extends TracingPlugin {
230
195
'openai.request.endpoint' : endpoint ,
231
196
'openai.request.method' : method . toUpperCase ( ) ,
232
197
233
- 'openai.organization.id' : body . organization_id , // only available in fine-tunes endpoints
234
- 'openai.organization.name' : headers [ 'openai-organization' ] ,
235
-
236
198
'openai.response.model' : headers [ 'openai-model' ] || body . model , // specific model, often undefined
237
- 'openai.response.id' : body . id , // common creation value, numeric epoch
238
199
'openai.response.deleted' : body . deleted , // common boolean field in delete responses
239
-
240
- // The OpenAI API appears to use both created and created_at in different places
241
- // Here we're conciously choosing to surface this inconsistency instead of normalizing
242
- 'openai.response.created' : body . created ,
243
- 'openai.response.created_at' : body . created_at
244
200
}
245
201
246
202
responseDataExtractionByMethod ( normalizedMethodName , tags , body , openaiStore )
@@ -510,13 +466,6 @@ function createChatCompletionRequestExtraction (tags, payload, openaiStore) {
510
466
if ( ! defensiveArrayLength ( messages ) ) return
511
467
512
468
openaiStore . messages = payload . messages
513
- for ( let i = 0 ; i < payload . messages . length ; i ++ ) {
514
- const message = payload . messages [ i ]
515
- tagChatCompletionRequestContent ( message . content , i , tags )
516
- tags [ `openai.request.messages.${ i } .role` ] = message . role
517
- tags [ `openai.request.messages.${ i } .name` ] = message . name
518
- tags [ `openai.request.messages.${ i } .finish_reason` ] = message . finish_reason
519
- }
520
469
}
521
470
522
471
function commonCreateImageRequestExtraction ( tags , payload , openaiStore ) {
@@ -728,13 +677,6 @@ function createRetrieveFileResponseExtraction (tags, body) {
728
677
729
678
function createEmbeddingResponseExtraction ( tags , body , openaiStore ) {
730
679
usageExtraction ( tags , body , openaiStore )
731
-
732
- if ( ! body . data ) return
733
-
734
- tags [ 'openai.response.embeddings_count' ] = body . data . length
735
- for ( let i = 0 ; i < body . data . length ; i ++ ) {
736
- tags [ `openai.response.embedding.${ i } .embedding_length` ] = body . data [ i ] . embedding . length
737
- }
738
680
}
739
681
740
682
function commonListCountResponseExtraction ( tags , body ) {
@@ -766,101 +708,14 @@ function commonCreateResponseExtraction (tags, body, openaiStore, methodName) {
766
708
767
709
if ( ! body . choices ) return
768
710
769
- tags [ 'openai.response.choices_count' ] = body . choices . length
770
-
771
711
openaiStore . choices = body . choices
772
-
773
- for ( let choiceIdx = 0 ; choiceIdx < body . choices . length ; choiceIdx ++ ) {
774
- const choice = body . choices [ choiceIdx ]
775
-
776
- // logprobs can be null and we still want to tag it as 'returned' even when set to 'null'
777
- const specifiesLogProb = Object . keys ( choice ) . includes ( 'logprobs' )
778
-
779
- tags [ `openai.response.choices.${ choiceIdx } .finish_reason` ] = choice . finish_reason
780
- tags [ `openai.response.choices.${ choiceIdx } .logprobs` ] = specifiesLogProb ? 'returned' : undefined
781
- tags [ `openai.response.choices.${ choiceIdx } .text` ] = normalize ( choice . text )
782
-
783
- // createChatCompletion only
784
- const message = choice . message || choice . delta // delta for streamed responses
785
- if ( message ) {
786
- tags [ `openai.response.choices.${ choiceIdx } .message.role` ] = message . role
787
- tags [ `openai.response.choices.${ choiceIdx } .message.content` ] = normalize ( message . content )
788
- tags [ `openai.response.choices.${ choiceIdx } .message.name` ] = normalize ( message . name )
789
- if ( message . tool_calls ) {
790
- const toolCalls = message . tool_calls
791
- for ( let toolIdx = 0 ; toolIdx < toolCalls . length ; toolIdx ++ ) {
792
- tags [ `openai.response.choices.${ choiceIdx } .message.tool_calls.${ toolIdx } .function.name` ] =
793
- toolCalls [ toolIdx ] . function . name
794
- tags [ `openai.response.choices.${ choiceIdx } .message.tool_calls.${ toolIdx } .function.arguments` ] =
795
- toolCalls [ toolIdx ] . function . arguments
796
- tags [ `openai.response.choices.${ choiceIdx } .message.tool_calls.${ toolIdx } .id` ] =
797
- toolCalls [ toolIdx ] . id
798
- }
799
- }
800
- }
801
- }
802
712
}
803
713
804
- // createCompletion, createChatCompletion, createEdit, createEmbedding
805
- function usageExtraction ( tags , body , methodName , openaiStore ) {
806
- let promptTokens = 0
807
- let completionTokens = 0
808
- let totalTokens = 0
809
- if ( body && body . usage ) {
810
- promptTokens = body . usage . prompt_tokens
811
- completionTokens = body . usage . completion_tokens
812
- totalTokens = body . usage . total_tokens
813
- } else if ( body . model && [ 'createChatCompletion' , 'createCompletion' ] . includes ( methodName ) ) {
814
- // estimate tokens based on method name for completions and chat completions
815
- const { model } = body
816
-
817
- // prompt tokens
818
- const payload = openaiStore
819
- const promptTokensCount = countPromptTokens ( methodName , payload , model )
820
- promptTokens = promptTokensCount . promptTokens
821
- const promptEstimated = promptTokensCount . promptEstimated
822
-
823
- // completion tokens
824
- const completionTokensCount = countCompletionTokens ( body , model )
825
- completionTokens = completionTokensCount . completionTokens
826
- const completionEstimated = completionTokensCount . completionEstimated
827
-
828
- // total tokens
829
- totalTokens = promptTokens + completionTokens
830
- if ( promptEstimated ) tags [ 'openai.response.usage.prompt_tokens_estimated' ] = true
831
- if ( completionEstimated ) tags [ 'openai.response.usage.completion_tokens_estimated' ] = true
832
- }
833
-
834
- if ( promptTokens != null ) tags [ 'openai.response.usage.prompt_tokens' ] = promptTokens
835
- if ( completionTokens != null ) tags [ 'openai.response.usage.completion_tokens' ] = completionTokens
836
- if ( totalTokens != null ) tags [ 'openai.response.usage.total_tokens' ] = totalTokens
837
- }
838
714
839
715
function truncateApiKey ( apiKey ) {
840
716
return apiKey && `sk-...${ apiKey . slice ( - 4 ) } `
841
717
}
842
718
843
- function tagChatCompletionRequestContent ( contents , messageIdx , tags ) {
844
- if ( typeof contents === 'string' ) {
845
- tags [ `openai.request.messages.${ messageIdx } .content` ] = normalize ( contents )
846
- } else if ( Array . isArray ( contents ) ) {
847
- // content can also be an array of objects
848
- // which represent text input or image url
849
- for ( const contentIdx in contents ) {
850
- const content = contents [ contentIdx ]
851
- const type = content . type
852
- tags [ `openai.request.messages.${ messageIdx } .content.${ contentIdx } .type` ] = content . type
853
- if ( type === 'text' ) {
854
- tags [ `openai.request.messages.${ messageIdx } .content.${ contentIdx } .text` ] = normalize ( content . text )
855
- } else if ( type === 'image_url' ) {
856
- tags [ `openai.request.messages.${ messageIdx } .content.${ contentIdx } .image_url.url` ] =
857
- normalize ( content . image_url . url )
858
- }
859
- // unsupported type otherwise, won't be tagged
860
- }
861
- }
862
- // unsupported type otherwise, won't be tagged
863
- }
864
719
865
720
// The server almost always responds with JSON
866
721
function coerceResponseBody ( body , methodName ) {
0 commit comments