mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-09-19 01:56: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 {
|
||||
return nil, errors.New("request is nil")
|
||||
}
|
||||
|
||||
c.Set("claude_model", request.Model)
|
||||
return ConvertRequest(*request), nil
|
||||
}
|
||||
|
||||
|
@ -53,14 +53,14 @@ func ConvertRequest(textRequest model.GeneralOpenAIRequest) *Request {
|
||||
|
||||
func streamResponseClaude2OpenAI(claudeResponse *Response) *openai.ChatCompletionsStreamResponse {
|
||||
var choice openai.ChatCompletionsStreamResponseChoice
|
||||
choice.Delta.Content = claudeResponse.Completion
|
||||
finishReason := stopReasonClaude2OpenAI(claudeResponse.StopReason)
|
||||
choice.Delta.Content = claudeResponse.Delta.Text
|
||||
finishReason := stopReasonClaude2OpenAI(claudeResponse.Delta.StopReason)
|
||||
if finishReason != "null" {
|
||||
choice.FinishReason = &finishReason
|
||||
}
|
||||
var response openai.ChatCompletionsStreamResponse
|
||||
response.Object = "chat.completion.chunk"
|
||||
response.Model = claudeResponse.Model
|
||||
// response.Model = claudeResponse.Model
|
||||
response.Choices = []openai.ChatCompletionsStreamResponseChoice{choice}
|
||||
return &response
|
||||
}
|
||||
@ -70,10 +70,10 @@ func responseClaude2OpenAI(claudeResponse *Response) *openai.TextResponse {
|
||||
Index: 0,
|
||||
Message: model.Message{
|
||||
Role: "assistant",
|
||||
Content: strings.TrimPrefix(claudeResponse.Completion, " "),
|
||||
Content: strings.TrimPrefix(claudeResponse.Delta.Text, " "),
|
||||
Name: nil,
|
||||
},
|
||||
FinishReason: stopReasonClaude2OpenAI(claudeResponse.StopReason),
|
||||
FinishReason: stopReasonClaude2OpenAI(claudeResponse.Delta.StopReason),
|
||||
}
|
||||
fullTextResponse := openai.TextResponse{
|
||||
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
|
||||
data = strings.TrimSuffix(data, "\r")
|
||||
var claudeResponse Response
|
||||
|
||||
err := json.Unmarshal([]byte(data), &claudeResponse)
|
||||
if err != nil {
|
||||
logger.SysError("error unmarshalling stream response: " + err.Error())
|
||||
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.Id = responseId
|
||||
response.Created = createdTime
|
||||
@ -176,7 +195,7 @@ func Handler(c *gin.Context, resp *http.Response, promptTokens int, modelName st
|
||||
}
|
||||
fullTextResponse := responseClaude2OpenAI(&claudeResponse)
|
||||
fullTextResponse.Model = modelName
|
||||
completionTokens := openai.CountTokenText(claudeResponse.Completion, modelName)
|
||||
completionTokens := openai.CountTokenText(claudeResponse.Delta.Text, modelName)
|
||||
usage := model.Usage{
|
||||
PromptTokens: promptTokens,
|
||||
CompletionTokens: completionTokens,
|
||||
|
@ -19,9 +19,30 @@ type Error struct {
|
||||
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 {
|
||||
Completion string `json:"completion"`
|
||||
StopReason string `json:"stop_reason"`
|
||||
Model string `json:"model"`
|
||||
Error Error `json:"error"`
|
||||
Type ResponseType `json:"type"`
|
||||
Index int `json:"index,omitempty"`
|
||||
Delta struct {
|
||||
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