Skip to content

Commit 817061c

Browse files
authored
remove dependency for ai-statistic (alibaba#1660)
1 parent ea0d5e7 commit 817061c

File tree

1 file changed

+37
-20
lines changed
  • plugins/wasm-go/extensions/ai-quota

1 file changed

+37
-20
lines changed

plugins/wasm-go/extensions/ai-quota/main.go

+37-20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"errors"
67
"fmt"
@@ -215,35 +216,51 @@ func onHttpStreamingResponseBody(ctx wrapper.HttpContext, config QuotaConfig, da
215216
if chatMode == ChatModeNone || chatMode == ChatModeAdmin {
216217
return data
217218
}
219+
var inputToken, outputToken int64
220+
var consumer string
221+
if inputToken, outputToken, ok := getUsage(data); ok {
222+
ctx.SetContext("input_token", inputToken)
223+
ctx.SetContext("output_token", outputToken)
224+
}
225+
218226
// chat completion mode
219227
if !endOfStream {
220228
return data
221229
}
222-
inputTokenStr, err := proxywasm.GetProperty([]string{"filter_state", "wasm.input_token"})
223-
if err != nil {
224-
return data
225-
}
226-
outputTokenStr, err := proxywasm.GetProperty([]string{"filter_state", "wasm.output_token"})
227-
if err != nil {
228-
return data
229-
}
230-
inputToken, err := strconv.Atoi(string(inputTokenStr))
231-
if err != nil {
232-
return data
233-
}
234-
outputToken, err := strconv.Atoi(string(outputTokenStr))
235-
if err != nil {
230+
231+
if ctx.GetContext("input_token") == nil || ctx.GetContext("output_token") == nil || ctx.GetContext("consumer") == nil {
236232
return data
237233
}
238-
consumer, ok := ctx.GetContext("consumer").(string)
239-
if ok {
240-
totalToken := int(inputToken + outputToken)
241-
log.Debugf("update consumer:%s, totalToken:%d", consumer, totalToken)
242-
config.redisClient.DecrBy(config.RedisKeyPrefix+consumer, totalToken, nil)
243-
}
234+
235+
inputToken = ctx.GetContext("input_token").(int64)
236+
outputToken = ctx.GetContext("output_token").(int64)
237+
consumer = ctx.GetContext("consumer").(string)
238+
totalToken := int(inputToken + outputToken)
239+
log.Debugf("update consumer:%s, totalToken:%d", consumer, totalToken)
240+
config.redisClient.DecrBy(config.RedisKeyPrefix+consumer, totalToken, nil)
244241
return data
245242
}
246243

244+
func getUsage(data []byte) (inputTokenUsage int64, outputTokenUsage int64, ok bool) {
245+
chunks := bytes.Split(bytes.TrimSpace(data), []byte("\n\n"))
246+
for _, chunk := range chunks {
247+
// the feature strings are used to identify the usage data, like:
248+
// {"model":"gpt2","usage":{"prompt_tokens":1,"completion_tokens":1}}
249+
if !bytes.Contains(chunk, []byte("prompt_tokens")) || !bytes.Contains(chunk, []byte("completion_tokens")) {
250+
continue
251+
}
252+
inputTokenObj := gjson.GetBytes(chunk, "usage.prompt_tokens")
253+
outputTokenObj := gjson.GetBytes(chunk, "usage.completion_tokens")
254+
if inputTokenObj.Exists() && outputTokenObj.Exists() {
255+
inputTokenUsage = inputTokenObj.Int()
256+
outputTokenUsage = outputTokenObj.Int()
257+
ok = true
258+
return
259+
}
260+
}
261+
return
262+
}
263+
247264
func deniedNoKeyAuthData() types.Action {
248265
util.SendResponse(http.StatusUnauthorized, "ai-quota.no_key", "text/plain", "Request denied by ai quota check. No Key Authentication information found.")
249266
return types.ActionContinue

0 commit comments

Comments
 (0)