@@ -59,7 +59,6 @@ const (
59
59
LLMDurationCount = "llm_duration_count"
60
60
LLMStreamDurationCount = "llm_stream_duration_count"
61
61
ResponseType = "response_type"
62
- ChatID = "chat_id"
63
62
ChatRound = "chat_round"
64
63
65
64
// Inner span attributes
@@ -192,6 +191,9 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config AIStatisticsConfig) ty
192
191
if consumer , _ := proxywasm .GetHttpRequestHeader (ConsumerKey ); consumer != "" {
193
192
ctx .SetContext (ConsumerKey , consumer )
194
193
}
194
+ if requestModel , _ := proxywasm .GetHttpRequestHeader ("x-higress-llm-model" ); requestModel != "" {
195
+ ctx .SetContext (tokenusage .CtxKeyRequestModel , requestModel )
196
+ }
195
197
196
198
ctx .SetRequestBodyBufferLimit (defaultMaxBodyBytes )
197
199
@@ -214,14 +216,15 @@ func onHttpRequestBody(ctx wrapper.HttpContext, config AIStatisticsConfig, body
214
216
requestModel = model .String ()
215
217
} else {
216
218
requestPath := ctx .GetStringContext (RequestPath , "" )
217
- if strings .Contains (requestPath , "generateContent" ) || strings .Contains (requestPath , "streamGenerateContent" ) { // Google Gemini GenerateContent
218
- reg := regexp .MustCompile (`^.*/(?P<api_version>[^/]+)/models/(?P<model>[^:]+):\w+Content$` )
219
+ if strings .Contains (requestPath , "generateContent" ) || strings .Contains (requestPath , "streamGenerateContent" ) || strings . Contains ( requestPath , "countTokens" ) || strings . Contains ( requestPath , "predictLongRunning" ) { // Google Gemini GenerateContent
220
+ reg := regexp .MustCompile (`^.*/(?P<api_version>[^/]+)/models/(?P<model>[^:]+):( \w+Content|countTokens|predictLongRunning) $` )
219
221
matches := reg .FindStringSubmatch (requestPath )
220
222
if len (matches ) == 3 {
221
223
requestModel = matches [2 ]
222
224
}
223
225
}
224
226
}
227
+ ctx .SetContext (tokenusage .CtxKeyRequestModel , requestModel )
225
228
setSpanAttribute (ArmsRequestModel , requestModel )
226
229
// Set the number of conversation rounds
227
230
@@ -242,7 +245,7 @@ func onHttpRequestBody(ctx wrapper.HttpContext, config AIStatisticsConfig, body
242
245
ctx .SetUserAttribute (ChatRound , userPromptCount )
243
246
244
247
// Write log
245
- ctx .WriteUserAttributeToLogWithKey (wrapper .AILogKey )
248
+ _ = ctx .WriteUserAttributeToLogWithKey (wrapper .AILogKey )
246
249
return types .ActionContinue
247
250
}
248
251
@@ -271,14 +274,8 @@ func onHttpStreamingBody(ctx wrapper.HttpContext, config AIStatisticsConfig, dat
271
274
}
272
275
273
276
ctx .SetUserAttribute (ResponseType , "stream" )
274
- if chatID := wrapper .GetValueFromBody (data , []string {
275
- "id" ,
276
- "response.id" ,
277
- "responseId" , // Gemini generateContent
278
- "message.id" , // anthropic messages
279
- }); chatID != nil {
280
- ctx .SetUserAttribute (ChatID , chatID .String ())
281
- }
277
+
278
+ tokenusage .ExtractChatId (ctx , data )
282
279
283
280
// Get requestStartTime from http context
284
281
requestStartTime , ok := ctx .GetContext (StatisticsRequestStartTime ).(int64 )
@@ -319,7 +316,7 @@ func onHttpStreamingBody(ctx wrapper.HttpContext, config AIStatisticsConfig, dat
319
316
}
320
317
321
318
// Write log
322
- ctx .WriteUserAttributeToLogWithKey (wrapper .AILogKey )
319
+ _ = ctx .WriteUserAttributeToLogWithKey (wrapper .AILogKey )
323
320
324
321
// Write metrics
325
322
writeMetric (ctx , config )
@@ -335,14 +332,8 @@ func onHttpResponseBody(ctx wrapper.HttpContext, config AIStatisticsConfig, body
335
332
ctx .SetUserAttribute (LLMServiceDuration , responseEndTime - requestStartTime )
336
333
337
334
ctx .SetUserAttribute (ResponseType , "normal" )
338
- if chatID := wrapper .GetValueFromBody (body , []string {
339
- "id" ,
340
- "response.id" ,
341
- "responseId" , // Gemini generateContent
342
- "message.id" , // anthropic messages
343
- }); chatID != nil {
344
- ctx .SetUserAttribute (ChatID , chatID .String ())
345
- }
335
+
336
+ tokenusage .ExtractChatId (ctx , body )
346
337
347
338
// Set information about this request
348
339
if ! config .disableOpenaiUsage {
@@ -359,7 +350,7 @@ func onHttpResponseBody(ctx wrapper.HttpContext, config AIStatisticsConfig, body
359
350
setAttributeBySource (ctx , config , ResponseBody , body )
360
351
361
352
// Write log
362
- ctx .WriteUserAttributeToLogWithKey (wrapper .AILogKey )
353
+ _ = ctx .WriteUserAttributeToLogWithKey (wrapper .AILogKey )
363
354
364
355
// Write metrics
365
356
writeMetric (ctx , config )
@@ -372,7 +363,7 @@ func onHttpResponseBody(ctx wrapper.HttpContext, config AIStatisticsConfig, body
372
363
func setAttributeBySource (ctx wrapper.HttpContext , config AIStatisticsConfig , source string , body []byte ) {
373
364
for _ , attribute := range config .attributes {
374
365
var key string
375
- var value interface {}
366
+ var value any
376
367
if source == attribute .ValueSource {
377
368
key = attribute .Key
378
369
switch source {
@@ -418,9 +409,9 @@ func setAttributeBySource(ctx wrapper.HttpContext, config AIStatisticsConfig, so
418
409
}
419
410
}
420
411
421
- func extractStreamingBodyByJsonPath (data []byte , jsonPath string , rule string ) interface {} {
412
+ func extractStreamingBodyByJsonPath (data []byte , jsonPath string , rule string ) any {
422
413
chunks := bytes .Split (bytes .TrimSpace (wrapper .UnifySSEChunk (data )), []byte ("\n \n " ))
423
- var value interface {}
414
+ var value any
424
415
if rule == RuleFirst {
425
416
for _ , chunk := range chunks {
426
417
jsonObj := gjson .GetBytes (chunk , jsonPath )
@@ -453,10 +444,10 @@ func extractStreamingBodyByJsonPath(data []byte, jsonPath string, rule string) i
453
444
}
454
445
455
446
// Set the tracing span with value.
456
- func setSpanAttribute (key string , value interface {} ) {
447
+ func setSpanAttribute (key string , value any ) {
457
448
if value != "" {
458
449
traceSpanTag := wrapper .TraceSpanTagPrefix + key
459
- if e := proxywasm .SetProperty ([]string {traceSpanTag }, [] byte ( fmt .Sprint ( value ) )); e != nil {
450
+ if e := proxywasm .SetProperty ([]string {traceSpanTag }, fmt .Append ( nil , value )); e != nil {
460
451
log .Warnf ("failed to set %s in filter state: %v" , traceSpanTag , e )
461
452
}
462
453
} else {
@@ -532,7 +523,7 @@ func writeMetric(ctx wrapper.HttpContext, config AIStatisticsConfig) {
532
523
}
533
524
}
534
525
535
- func convertToUInt (val interface {} ) (uint64 , bool ) {
526
+ func convertToUInt (val any ) (uint64 , bool ) {
536
527
switch v := val .(type ) {
537
528
case float32 :
538
529
return uint64 (v ), true
0 commit comments