model_mapped.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package helper
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "strings"
  7. "github.com/QuantumNous/new-api/dto"
  8. "github.com/QuantumNous/new-api/relay/common"
  9. relayconstant "github.com/QuantumNous/new-api/relay/constant"
  10. "github.com/QuantumNous/new-api/setting/ratio_setting"
  11. "github.com/gin-gonic/gin"
  12. )
  13. func ModelMappedHelper(c *gin.Context, info *common.RelayInfo, request dto.Request) error {
  14. if info.ChannelMeta == nil {
  15. info.ChannelMeta = &common.ChannelMeta{}
  16. }
  17. isResponsesCompact := info.RelayMode == relayconstant.RelayModeResponsesCompact
  18. originModelName := info.OriginModelName
  19. mappingModelName := originModelName
  20. if isResponsesCompact && strings.HasSuffix(originModelName, ratio_setting.CompactModelSuffix) {
  21. mappingModelName = strings.TrimSuffix(originModelName, ratio_setting.CompactModelSuffix)
  22. }
  23. // map model name
  24. modelMapping := c.GetString("model_mapping")
  25. if modelMapping != "" && modelMapping != "{}" {
  26. modelMap := make(map[string]string)
  27. err := json.Unmarshal([]byte(modelMapping), &modelMap)
  28. if err != nil {
  29. return fmt.Errorf("unmarshal_model_mapping_failed")
  30. }
  31. // 支持链式模型重定向,最终使用链尾的模型
  32. currentModel := mappingModelName
  33. visitedModels := map[string]bool{
  34. currentModel: true,
  35. }
  36. for {
  37. if mappedModel, exists := modelMap[currentModel]; exists && mappedModel != "" {
  38. // 模型重定向循环检测,避免无限循环
  39. if visitedModels[mappedModel] {
  40. if mappedModel == currentModel {
  41. if currentModel == info.OriginModelName {
  42. info.IsModelMapped = false
  43. return nil
  44. } else {
  45. info.IsModelMapped = true
  46. break
  47. }
  48. }
  49. return errors.New("model_mapping_contains_cycle")
  50. }
  51. visitedModels[mappedModel] = true
  52. currentModel = mappedModel
  53. info.IsModelMapped = true
  54. } else {
  55. break
  56. }
  57. }
  58. if info.IsModelMapped {
  59. info.UpstreamModelName = currentModel
  60. }
  61. }
  62. if isResponsesCompact {
  63. finalUpstreamModelName := mappingModelName
  64. if info.IsModelMapped && info.UpstreamModelName != "" {
  65. finalUpstreamModelName = info.UpstreamModelName
  66. }
  67. info.UpstreamModelName = finalUpstreamModelName
  68. info.OriginModelName = ratio_setting.WithCompactModelSuffix(finalUpstreamModelName)
  69. }
  70. if request != nil {
  71. request.SetModelName(info.UpstreamModelName)
  72. }
  73. return nil
  74. }