feat: 启用函数计费

This commit is contained in:
CaIon 2024-04-22 16:35:56 +08:00
parent 76dc7af8d1
commit bdc65bdba2
4 changed files with 68 additions and 22 deletions

View File

@ -12,23 +12,24 @@ import (
// TODO: when a new api is enabled, check the pricing here // TODO: when a new api is enabled, check the pricing here
// 1 === $0.002 / 1K tokens // 1 === $0.002 / 1K tokens
// 1 === ¥0.014 / 1k tokens // 1 === ¥0.014 / 1k tokens
var DefaultModelRatio = map[string]float64{ var DefaultModelRatio = map[string]float64{
//"midjourney": 50, //"midjourney": 50,
"gpt-4-gizmo-*": 15, "gpt-4-gizmo-*": 15,
"gpt-4": 15, "gpt-4": 15,
"gpt-4-0314": 15, //"gpt-4-0314": 15, //deprecated
"gpt-4-0613": 15, "gpt-4-0613": 15,
"gpt-4-32k": 30, "gpt-4-32k": 30,
"gpt-4-32k-0314": 30, //"gpt-4-32k-0314": 30, //deprecated
"gpt-4-32k-0613": 30, "gpt-4-32k-0613": 30,
"gpt-4-1106-preview": 5, // $0.01 / 1K tokens "gpt-4-1106-preview": 5, // $0.01 / 1K tokens
"gpt-4-0125-preview": 5, // $0.01 / 1K tokens "gpt-4-0125-preview": 5, // $0.01 / 1K tokens
"gpt-4-turbo-preview": 5, // $0.01 / 1K tokens "gpt-4-turbo-preview": 5, // $0.01 / 1K tokens
"gpt-4-vision-preview": 5, // $0.01 / 1K tokens "gpt-4-vision-preview": 5, // $0.01 / 1K tokens
"gpt-4-1106-vision-preview": 5, // $0.01 / 1K tokens "gpt-4-1106-vision-preview": 5, // $0.01 / 1K tokens
"gpt-4-turbo": 5, // $0.01 / 1K tokens "gpt-4-turbo": 5, // $0.01 / 1K tokens
"gpt-3.5-turbo": 0.25, // $0.0015 / 1K tokens "gpt-3.5-turbo": 0.25, // $0.0015 / 1K tokens
"gpt-3.5-turbo-0301": 0.75, //"gpt-3.5-turbo-0301": 0.75, //deprecated
"gpt-3.5-turbo-0613": 0.75, "gpt-3.5-turbo-0613": 0.75,
"gpt-3.5-turbo-16k": 1.5, // $0.003 / 1K tokens "gpt-3.5-turbo-16k": 1.5, // $0.003 / 1K tokens
"gpt-3.5-turbo-16k-0613": 1.5, "gpt-3.5-turbo-16k-0613": 1.5,

View File

@ -54,13 +54,29 @@ type OpenAIEmbeddingResponse struct {
} }
type ChatCompletionsStreamResponseChoice struct { type ChatCompletionsStreamResponseChoice struct {
Delta struct { Delta ChatCompletionsStreamResponseChoiceDelta `json:"delta"`
Content string `json:"content"` FinishReason *string `json:"finish_reason,omitempty"`
Role string `json:"role,omitempty"` Index int `json:"index,omitempty"`
ToolCalls any `json:"tool_calls,omitempty"` }
} `json:"delta"`
FinishReason *string `json:"finish_reason,omitempty"` type ChatCompletionsStreamResponseChoiceDelta struct {
Index int `json:"index,omitempty"` Content string `json:"content"`
Role string `json:"role,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
}
type ToolCall struct {
// Index is not nil only in chat completion chunk object
Index *int `json:"index,omitempty"`
ID string `json:"id"`
Type any `json:"type"`
Function FunctionCall `json:"function"`
}
type FunctionCall struct {
Name string `json:"name,omitempty"`
// call function with arguments in JSON format
Arguments string `json:"arguments,omitempty"`
} }
type ChatCompletionsStreamResponse struct { type ChatCompletionsStreamResponse struct {

View File

@ -68,6 +68,12 @@ func OpenaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*d
if err == nil { if err == nil {
for _, choice := range streamResponse.Choices { for _, choice := range streamResponse.Choices {
responseTextBuilder.WriteString(choice.Delta.Content) responseTextBuilder.WriteString(choice.Delta.Content)
if choice.Delta.ToolCalls != nil {
for _, tool := range choice.Delta.ToolCalls {
responseTextBuilder.WriteString(tool.Function.Name)
responseTextBuilder.WriteString(tool.Function.Arguments)
}
}
} }
} }
} }
@ -75,6 +81,12 @@ func OpenaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*d
for _, streamResponse := range streamResponses { for _, streamResponse := range streamResponses {
for _, choice := range streamResponse.Choices { for _, choice := range streamResponse.Choices {
responseTextBuilder.WriteString(choice.Delta.Content) responseTextBuilder.WriteString(choice.Delta.Content)
if choice.Delta.ToolCalls != nil {
for _, tool := range choice.Delta.ToolCalls {
responseTextBuilder.WriteString(tool.Function.Name)
responseTextBuilder.WriteString(tool.Function.Arguments)
}
}
} }
} }
} }

View File

@ -211,6 +211,23 @@ func CountTokenInput(input any, model string, check bool) (int, error, bool) {
return CountTokenInput(fmt.Sprintf("%v", input), model, check) return CountTokenInput(fmt.Sprintf("%v", input), model, check)
} }
func CountTokenStreamChoices(messages []dto.ChatCompletionsStreamResponseChoice, model string) int {
tokens := 0
for _, message := range messages {
tkm, _, _ := CountTokenInput(message.Delta.Content, model, false)
tokens += tkm
if message.Delta.ToolCalls != nil {
for _, tool := range message.Delta.ToolCalls {
tkm, _, _ := CountTokenInput(tool.Function.Name, model, false)
tokens += tkm
tkm, _, _ = CountTokenInput(tool.Function.Arguments, model, false)
tokens += tkm
}
}
}
return tokens
}
func CountAudioToken(text string, model string, check bool) (int, error, bool) { func CountAudioToken(text string, model string, check bool) (int, error, bool) {
if strings.HasPrefix(model, "tts") { if strings.HasPrefix(model, "tts") {
contains, words := SensitiveWordContains(text) contains, words := SensitiveWordContains(text)