| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- package aws
- import (
- "context"
- "encoding/json"
- "io"
- "net/http"
- "strings"
- "github.com/QuantumNous/new-api/common"
- "github.com/QuantumNous/new-api/dto"
- "github.com/QuantumNous/new-api/logger"
- )
- type AwsClaudeRequest struct {
- // AnthropicVersion should be "bedrock-2023-05-31"
- AnthropicVersion string `json:"anthropic_version"`
- AnthropicBeta json.RawMessage `json:"anthropic_beta,omitempty"`
- System any `json:"system,omitempty"`
- Messages []dto.ClaudeMessage `json:"messages"`
- MaxTokens uint `json:"max_tokens,omitempty"`
- Temperature *float64 `json:"temperature,omitempty"`
- TopP float64 `json:"top_p,omitempty"`
- TopK int `json:"top_k,omitempty"`
- StopSequences []string `json:"stop_sequences,omitempty"`
- Tools any `json:"tools,omitempty"`
- ToolChoice any `json:"tool_choice,omitempty"`
- Thinking *dto.Thinking `json:"thinking,omitempty"`
- OutputConfig json.RawMessage `json:"output_config,omitempty"`
- }
- func formatRequest(requestBody io.Reader, requestHeader http.Header) (*AwsClaudeRequest, error) {
- var awsClaudeRequest AwsClaudeRequest
- err := common.DecodeJson(requestBody, &awsClaudeRequest)
- if err != nil {
- return nil, err
- }
- awsClaudeRequest.AnthropicVersion = "bedrock-2023-05-31"
- // check header anthropic-beta
- anthropicBetaValues := requestHeader.Get("anthropic-beta")
- if len(anthropicBetaValues) > 0 {
- var tempArray []string
- tempArray = strings.Split(anthropicBetaValues, ",")
- if len(tempArray) > 0 {
- betaJson, err := json.Marshal(tempArray)
- if err != nil {
- return nil, err
- }
- awsClaudeRequest.AnthropicBeta = betaJson
- }
- }
- logger.LogJson(context.Background(), "json", awsClaudeRequest)
- return &awsClaudeRequest, nil
- }
- // NovaMessage Nova模型使用messages-v1格式
- type NovaMessage struct {
- Role string `json:"role"`
- Content []NovaContent `json:"content"`
- }
- type NovaContent struct {
- Text string `json:"text"`
- }
- type NovaRequest struct {
- SchemaVersion string `json:"schemaVersion"` // 请求版本,例如 "1.0"
- Messages []NovaMessage `json:"messages"` // 对话消息列表
- InferenceConfig *NovaInferenceConfig `json:"inferenceConfig,omitempty"` // 推理配置,可选
- }
- type NovaInferenceConfig struct {
- MaxTokens int `json:"maxTokens,omitempty"` // 最大生成的 token 数
- Temperature float64 `json:"temperature,omitempty"` // 随机性 (默认 0.7, 范围 0-1)
- TopP float64 `json:"topP,omitempty"` // nucleus sampling (默认 0.9, 范围 0-1)
- TopK int `json:"topK,omitempty"` // 限制候选 token 数 (默认 50, 范围 0-128)
- StopSequences []string `json:"stopSequences,omitempty"` // 停止生成的序列
- }
- // 转换OpenAI请求为Nova格式
- func convertToNovaRequest(req *dto.GeneralOpenAIRequest) *NovaRequest {
- novaMessages := make([]NovaMessage, len(req.Messages))
- for i, msg := range req.Messages {
- novaMessages[i] = NovaMessage{
- Role: msg.Role,
- Content: []NovaContent{{Text: msg.StringContent()}},
- }
- }
- novaReq := &NovaRequest{
- SchemaVersion: "messages-v1",
- Messages: novaMessages,
- }
- // 设置推理配置
- if req.MaxTokens != 0 || (req.Temperature != nil && *req.Temperature != 0) || req.TopP != 0 || req.TopK != 0 || req.Stop != nil {
- novaReq.InferenceConfig = &NovaInferenceConfig{}
- if req.MaxTokens != 0 {
- novaReq.InferenceConfig.MaxTokens = int(req.MaxTokens)
- }
- if req.Temperature != nil && *req.Temperature != 0 {
- novaReq.InferenceConfig.Temperature = *req.Temperature
- }
- if req.TopP != 0 {
- novaReq.InferenceConfig.TopP = req.TopP
- }
- if req.TopK != 0 {
- novaReq.InferenceConfig.TopK = req.TopK
- }
- if req.Stop != nil {
- if stopSequences := parseStopSequences(req.Stop); len(stopSequences) > 0 {
- novaReq.InferenceConfig.StopSequences = stopSequences
- }
- }
- }
- return novaReq
- }
- // parseStopSequences 解析停止序列,支持字符串或字符串数组
- func parseStopSequences(stop any) []string {
- if stop == nil {
- return nil
- }
- switch v := stop.(type) {
- case string:
- if v != "" {
- return []string{v}
- }
- case []string:
- return v
- case []interface{}:
- var sequences []string
- for _, item := range v {
- if str, ok := item.(string); ok && str != "" {
- sequences = append(sequences, str)
- }
- }
- return sequences
- }
- return nil
- }
|