From e052009eba1065950c5554fbaddb2065cd6466a6 Mon Sep 17 00:00:00 2001 From: MartialBE Date: Tue, 2 Jan 2024 22:40:47 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20xunfei=20support=20function?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + providers/xunfei/chat.go | 37 ++++++++++++++++++++++++++---- providers/xunfei/type.go | 49 ++++++++++++++++++++++++++-------------- types/chat.go | 38 ++++++++++++++++++++++++------- 4 files changed, 95 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index af989b72..67acb98d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ build logs data tmp/ +test/ .env \ No newline at end of file diff --git a/providers/xunfei/chat.go b/providers/xunfei/chat.go index 9a8c1317..c3b94ec9 100644 --- a/providers/xunfei/chat.go +++ b/providers/xunfei/chat.go @@ -115,6 +115,16 @@ func (p *XunfeiProvider) requestOpenAI2Xunfei(request *types.ChatCompletionReque } } xunfeiRequest := XunfeiChatRequest{} + + if request.Tools != nil { + functions := make([]*types.ChatCompletionFunction, 0, len(request.Tools)) + for _, tool := range request.Tools { + functions = append(functions, &tool.Function) + } + xunfeiRequest.Payload.Functions = &XunfeiChatPayloadFunctions{} + xunfeiRequest.Payload.Functions.Text = functions + } + xunfeiRequest.Header.AppId = p.apiId xunfeiRequest.Parameter.Chat.Domain = p.domain xunfeiRequest.Parameter.Chat.Temperature = request.Temperature @@ -132,14 +142,31 @@ func (p *XunfeiProvider) responseXunfei2OpenAI(response *XunfeiChatResponse) *ty }, } } + choice := types.ChatCompletionChoice{ - Index: 0, - Message: types.ChatCompletionMessage{ - Role: "assistant", - Content: response.Payload.Choices.Text[0].Content, - }, + Index: 0, FinishReason: base.StopFinishReason, } + + xunfeiText := response.Payload.Choices.Text[0] + + if xunfeiText.FunctionCall != nil { + choice.Message = types.ChatCompletionMessage{ + Role: "assistant", + ToolCalls: []*types.ChatCompletionToolCalls{ + { + Type: "function", + Function: *xunfeiText.FunctionCall, + }, + }, + } + } else { + choice.Message = types.ChatCompletionMessage{ + Role: "assistant", + Content: xunfeiText.Content, + } + } + fullTextResponse := types.ChatCompletionResponse{ Object: "chat.completion", Created: common.GetTimestamp(), diff --git a/providers/xunfei/type.go b/providers/xunfei/type.go index 23fdef6a..b74d064d 100644 --- a/providers/xunfei/type.go +++ b/providers/xunfei/type.go @@ -7,30 +7,45 @@ type XunfeiMessage struct { Content string `json:"content"` } +type XunfeiChatPayloadMessage struct { + Text []XunfeiMessage `json:"text"` +} + +type XunfeiChatPayloadFunctions struct { + Text []*types.ChatCompletionFunction `json:"text"` +} + +type XunfeiChatPayload struct { + Message XunfeiChatPayloadMessage `json:"message"` + Functions *XunfeiChatPayloadFunctions `json:"functions,omitempty"` +} + +type XunfeiParameterChat struct { + Domain string `json:"domain,omitempty"` + Temperature float64 `json:"temperature,omitempty"` + TopK int `json:"top_k,omitempty"` + MaxTokens int `json:"max_tokens,omitempty"` + Auditing bool `json:"auditing,omitempty"` +} + +type XunfeiChatRequestParameter struct { + Chat XunfeiParameterChat `json:"chat"` +} + type XunfeiChatRequest struct { Header struct { AppId string `json:"app_id"` } `json:"header"` - Parameter struct { - Chat struct { - Domain string `json:"domain,omitempty"` - Temperature float64 `json:"temperature,omitempty"` - TopK int `json:"top_k,omitempty"` - MaxTokens int `json:"max_tokens,omitempty"` - Auditing bool `json:"auditing,omitempty"` - } `json:"chat"` - } `json:"parameter"` - Payload struct { - Message struct { - Text []XunfeiMessage `json:"text"` - } `json:"message"` - } `json:"payload"` + Parameter XunfeiChatRequestParameter `json:"parameter"` + Payload XunfeiChatPayload `json:"payload"` } type XunfeiChatResponseTextItem struct { - Content string `json:"content"` - Role string `json:"role"` - Index int `json:"index"` + Content string `json:"content"` + Role string `json:"role"` + Index int `json:"index"` + ContentType string `json:"content_type,omitempty"` + FunctionCall *types.ChatCompletionToolCallsFunction `json:"function_call,omitempty"` } type XunfeiChatResponse struct { diff --git a/types/chat.go b/types/chat.go index 5aba69b2..701e9b86 100644 --- a/types/chat.go +++ b/types/chat.go @@ -5,13 +5,24 @@ const ( ContentTypeImageURL = "image_url" ) +type ChatCompletionToolCallsFunction struct { + Name string `json:"name"` + Arguments string `json:"arguments"` +} + +type ChatCompletionToolCalls struct { + Id string `json:"id"` + Type string `json:"type"` + Function ChatCompletionToolCallsFunction `json:"function"` +} + type ChatCompletionMessage struct { - Role string `json:"role"` - Content any `json:"content"` - Name *string `json:"name,omitempty"` - FunctionCall any `json:"function_call,omitempty"` - ToolCalls any `json:"tool_calls,omitempty"` - ToolCallID string `json:"tool_call_id,omitempty"` + Role string `json:"role"` + Content any `json:"content,omitempty"` + Name *string `json:"name,omitempty"` + FunctionCall *ChatCompletionToolCallsFunction `json:"function_call,omitempty"` + ToolCalls []*ChatCompletionToolCalls `json:"tool_calls,omitempty"` + ToolCallID string `json:"tool_call_id,omitempty"` } func (m ChatCompletionMessage) StringContent() string { @@ -112,12 +123,23 @@ type ChatCompletionRequest struct { FrequencyPenalty float64 `json:"frequency_penalty,omitempty"` LogitBias any `json:"logit_bias,omitempty"` User string `json:"user,omitempty"` - Functions any `json:"functions,omitempty"` + Functions []*ChatCompletionFunction `json:"functions,omitempty"` FunctionCall any `json:"function_call,omitempty"` - Tools any `json:"tools,omitempty"` + Tools []*ChatCompletionTool `json:"tools,omitempty"` ToolChoice any `json:"tool_choice,omitempty"` } +type ChatCompletionFunction struct { + Name string `json:"name"` + Description string `json:"description"` + Parameters any `json:"parameters"` +} + +type ChatCompletionTool struct { + Type string `json:"type"` + Function ChatCompletionFunction `json:"function"` +} + type ChatCompletionChoice struct { Index int `json:"index"` Message ChatCompletionMessage `json:"message"`