mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-09-19 10:06:37 +08:00
Refactor: Anthropic model response proto update
- Refactor content response - Update channel adaptor to support `claude_model` - Remove `null` stop reasons from content responses - Add logging for error responses - Change content start, ping, and message delta types to return true - Set stop reason to end turn when response does not include a stop reason - Set content response stop reason to null - Add error handling for unmarshalling stream responses - Rename `Completion` to `Text` in type definitions and `StopReason` to `Delta.StopReason` - Count tokens in the `Delta.Text` field of the response instead of `Completion` - Remove `Model` from the full text response - Trim \r from incoming data
This commit is contained in:
parent
c8713a0212
commit
fdde066252
@ -41,6 +41,8 @@ func (a *Adaptor) ConvertRequest(c *gin.Context, relayMode int, request *model.G
|
|||||||
if request == nil {
|
if request == nil {
|
||||||
return nil, errors.New("request is nil")
|
return nil, errors.New("request is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Set("claude_model", request.Model)
|
||||||
return ConvertRequest(*request), nil
|
return ConvertRequest(*request), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,14 +53,14 @@ func ConvertRequest(textRequest model.GeneralOpenAIRequest) *Request {
|
|||||||
|
|
||||||
func streamResponseClaude2OpenAI(claudeResponse *Response) *openai.ChatCompletionsStreamResponse {
|
func streamResponseClaude2OpenAI(claudeResponse *Response) *openai.ChatCompletionsStreamResponse {
|
||||||
var choice openai.ChatCompletionsStreamResponseChoice
|
var choice openai.ChatCompletionsStreamResponseChoice
|
||||||
choice.Delta.Content = claudeResponse.Completion
|
choice.Delta.Content = claudeResponse.Delta.Text
|
||||||
finishReason := stopReasonClaude2OpenAI(claudeResponse.StopReason)
|
finishReason := stopReasonClaude2OpenAI(claudeResponse.Delta.StopReason)
|
||||||
if finishReason != "null" {
|
if finishReason != "null" {
|
||||||
choice.FinishReason = &finishReason
|
choice.FinishReason = &finishReason
|
||||||
}
|
}
|
||||||
var response openai.ChatCompletionsStreamResponse
|
var response openai.ChatCompletionsStreamResponse
|
||||||
response.Object = "chat.completion.chunk"
|
response.Object = "chat.completion.chunk"
|
||||||
response.Model = claudeResponse.Model
|
// response.Model = claudeResponse.Model
|
||||||
response.Choices = []openai.ChatCompletionsStreamResponseChoice{choice}
|
response.Choices = []openai.ChatCompletionsStreamResponseChoice{choice}
|
||||||
return &response
|
return &response
|
||||||
}
|
}
|
||||||
@ -70,10 +70,10 @@ func responseClaude2OpenAI(claudeResponse *Response) *openai.TextResponse {
|
|||||||
Index: 0,
|
Index: 0,
|
||||||
Message: model.Message{
|
Message: model.Message{
|
||||||
Role: "assistant",
|
Role: "assistant",
|
||||||
Content: strings.TrimPrefix(claudeResponse.Completion, " "),
|
Content: strings.TrimPrefix(claudeResponse.Delta.Text, " "),
|
||||||
Name: nil,
|
Name: nil,
|
||||||
},
|
},
|
||||||
FinishReason: stopReasonClaude2OpenAI(claudeResponse.StopReason),
|
FinishReason: stopReasonClaude2OpenAI(claudeResponse.Delta.StopReason),
|
||||||
}
|
}
|
||||||
fullTextResponse := openai.TextResponse{
|
fullTextResponse := openai.TextResponse{
|
||||||
Id: fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
|
Id: fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
|
||||||
@ -121,12 +121,31 @@ func StreamHandler(c *gin.Context, resp *http.Response) (*model.ErrorWithStatusC
|
|||||||
// some implementations may add \r at the end of data
|
// some implementations may add \r at the end of data
|
||||||
data = strings.TrimSuffix(data, "\r")
|
data = strings.TrimSuffix(data, "\r")
|
||||||
var claudeResponse Response
|
var claudeResponse Response
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(data), &claudeResponse)
|
err := json.Unmarshal([]byte(data), &claudeResponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.SysError("error unmarshalling stream response: " + err.Error())
|
logger.SysError("error unmarshalling stream response: " + err.Error())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
responseText += claudeResponse.Completion
|
|
||||||
|
switch claudeResponse.Type {
|
||||||
|
case TypeContentStart, TypePing, TypeMessageDelta:
|
||||||
|
return true
|
||||||
|
case TypeContentStop, TypeMessageStop:
|
||||||
|
if claudeResponse.Delta.StopReason == "" {
|
||||||
|
claudeResponse.Delta.StopReason = "end_turn"
|
||||||
|
}
|
||||||
|
case TypeContent:
|
||||||
|
claudeResponse.Delta.StopReason = "null"
|
||||||
|
case TypeError:
|
||||||
|
logger.SysError("error response: " + claudeResponse.Error.Message)
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
logger.SysError("unknown response type: " + string(data))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
responseText += claudeResponse.Delta.Text
|
||||||
response := streamResponseClaude2OpenAI(&claudeResponse)
|
response := streamResponseClaude2OpenAI(&claudeResponse)
|
||||||
response.Id = responseId
|
response.Id = responseId
|
||||||
response.Created = createdTime
|
response.Created = createdTime
|
||||||
@ -176,7 +195,7 @@ func Handler(c *gin.Context, resp *http.Response, promptTokens int, modelName st
|
|||||||
}
|
}
|
||||||
fullTextResponse := responseClaude2OpenAI(&claudeResponse)
|
fullTextResponse := responseClaude2OpenAI(&claudeResponse)
|
||||||
fullTextResponse.Model = modelName
|
fullTextResponse.Model = modelName
|
||||||
completionTokens := openai.CountTokenText(claudeResponse.Completion, modelName)
|
completionTokens := openai.CountTokenText(claudeResponse.Delta.Text, modelName)
|
||||||
usage := model.Usage{
|
usage := model.Usage{
|
||||||
PromptTokens: promptTokens,
|
PromptTokens: promptTokens,
|
||||||
CompletionTokens: completionTokens,
|
CompletionTokens: completionTokens,
|
||||||
|
@ -19,9 +19,30 @@ type Error struct {
|
|||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResponseType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
TypeError ResponseType = "error"
|
||||||
|
TypeStart ResponseType = "message_start"
|
||||||
|
TypeContentStart ResponseType = "content_block_start"
|
||||||
|
TypeContent ResponseType = "content_block_delta"
|
||||||
|
TypePing ResponseType = "ping"
|
||||||
|
TypeContentStop ResponseType = "content_block_stop"
|
||||||
|
TypeMessageDelta ResponseType = "message_delta"
|
||||||
|
TypeMessageStop ResponseType = "message_stop"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.anthropic.com/claude/reference/messages-streaming
|
||||||
type Response struct {
|
type Response struct {
|
||||||
Completion string `json:"completion"`
|
Type ResponseType `json:"type"`
|
||||||
StopReason string `json:"stop_reason"`
|
Index int `json:"index,omitempty"`
|
||||||
Model string `json:"model"`
|
Delta struct {
|
||||||
Error Error `json:"error"`
|
Type string `json:"type,omitempty"`
|
||||||
|
Text string `json:"text,omitempty"`
|
||||||
|
StopReason string `json:"stop_reason,omitempty"`
|
||||||
|
} `json:"delta,omitempty"`
|
||||||
|
Error struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
} `json:"error,omitempty"`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user