Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
ee0e1c97
authored
Jul 16, 2024
by
CalciumIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: audio relay
parent
7638a92d
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
555 additions
and
308 deletions
+555
-308
common/str.go
+73
-0
common/utils.go
+0
-60
controller/channel-test.go
+1
-1
controller/model.go
+1
-1
dto/audio.go
+27
-6
middleware/distributor.go
+11
-9
relay/channel/adapter.go
+3
-2
relay/channel/ali/adaptor.go
+8
-2
relay/channel/api_request.go
+32
-4
relay/channel/aws/adaptor.go
+7
-2
relay/channel/baidu/adaptor.go
+7
-2
relay/channel/claude/adaptor.go
+7
-2
relay/channel/cloudflare/adaptor.go
+9
-2
relay/channel/cohere/adaptor.go
+10
-2
relay/channel/dify/adaptor.go
+7
-2
relay/channel/gemini/adaptor.go
+9
-2
relay/channel/jina/adaptor.go
+9
-2
relay/channel/ollama/adaptor.go
+9
-2
relay/channel/openai/adaptor.go
+70
-14
relay/channel/openai/relay-openai.go
+137
-0
relay/channel/palm/adaptor.go
+7
-2
relay/channel/perplexity/adaptor.go
+7
-2
relay/channel/tencent/adaptor.go
+7
-2
relay/channel/xunfei/adaptor.go
+7
-2
relay/channel/zhipu/adaptor.go
+7
-2
relay/channel/zhipu_4v/adaptor.go
+7
-2
relay/constant/relay_mode.go
+7
-3
relay/relay-audio.go
+64
-171
relay/relay-text.go
+4
-4
relay/relay_rerank.go
+1
-1
No files found.
common/str.go
0 → 100644
View file @
ee0e1c97
package
common
import
(
"encoding/json"
"math/rand"
"strconv"
"unsafe"
)
func
GetStringIfEmpty
(
str
string
,
defaultValue
string
)
string
{
if
str
==
""
{
return
defaultValue
}
return
str
}
func
GetRandomString
(
length
int
)
string
{
//rand.Seed(time.Now().UnixNano())
key
:=
make
([]
byte
,
length
)
for
i
:=
0
;
i
<
length
;
i
++
{
key
[
i
]
=
keyChars
[
rand
.
Intn
(
len
(
keyChars
))]
}
return
string
(
key
)
}
func
MapToJsonStr
(
m
map
[
string
]
interface
{})
string
{
bytes
,
err
:=
json
.
Marshal
(
m
)
if
err
!=
nil
{
return
""
}
return
string
(
bytes
)
}
func
MapToJsonStrFloat
(
m
map
[
string
]
float64
)
string
{
bytes
,
err
:=
json
.
Marshal
(
m
)
if
err
!=
nil
{
return
""
}
return
string
(
bytes
)
}
func
StrToMap
(
str
string
)
map
[
string
]
interface
{}
{
m
:=
make
(
map
[
string
]
interface
{})
err
:=
json
.
Unmarshal
([]
byte
(
str
),
&
m
)
if
err
!=
nil
{
return
nil
}
return
m
}
func
String2Int
(
str
string
)
int
{
num
,
err
:=
strconv
.
Atoi
(
str
)
if
err
!=
nil
{
return
0
}
return
num
}
func
StringsContains
(
strs
[]
string
,
str
string
)
bool
{
for
_
,
s
:=
range
strs
{
if
s
==
str
{
return
true
}
}
return
false
}
// StringToByteSlice []byte only read, panic on append
func
StringToByteSlice
(
s
string
)
[]
byte
{
tmp1
:=
(
*
[
2
]
uintptr
)(
unsafe
.
Pointer
(
&
s
))
tmp2
:=
[
3
]
uintptr
{
tmp1
[
0
],
tmp1
[
1
],
tmp1
[
1
]}
return
*
(
*
[]
byte
)(
unsafe
.
Pointer
(
&
tmp2
))
}
common/utils.go
View file @
ee0e1c97
package
common
package
common
import
(
import
(
"encoding/json"
"fmt"
"fmt"
"github.com/google/uuid"
"github.com/google/uuid"
"html/template"
"html/template"
...
@@ -13,7 +12,6 @@ import (
...
@@ -13,7 +12,6 @@ import (
"strconv"
"strconv"
"strings"
"strings"
"time"
"time"
"unsafe"
)
)
func
OpenBrowser
(
url
string
)
{
func
OpenBrowser
(
url
string
)
{
...
@@ -159,15 +157,6 @@ func GenerateKey() string {
...
@@ -159,15 +157,6 @@ func GenerateKey() string {
return
string
(
key
)
return
string
(
key
)
}
}
func
GetRandomString
(
length
int
)
string
{
//rand.Seed(time.Now().UnixNano())
key
:=
make
([]
byte
,
length
)
for
i
:=
0
;
i
<
length
;
i
++
{
key
[
i
]
=
keyChars
[
rand
.
Intn
(
len
(
keyChars
))]
}
return
string
(
key
)
}
func
GetRandomInt
(
max
int
)
int
{
func
GetRandomInt
(
max
int
)
int
{
//rand.Seed(time.Now().UnixNano())
//rand.Seed(time.Now().UnixNano())
return
rand
.
Intn
(
max
)
return
rand
.
Intn
(
max
)
...
@@ -194,56 +183,7 @@ func MessageWithRequestId(message string, id string) string {
...
@@ -194,56 +183,7 @@ func MessageWithRequestId(message string, id string) string {
return
fmt
.
Sprintf
(
"%s (request id: %s)"
,
message
,
id
)
return
fmt
.
Sprintf
(
"%s (request id: %s)"
,
message
,
id
)
}
}
func
String2Int
(
str
string
)
int
{
num
,
err
:=
strconv
.
Atoi
(
str
)
if
err
!=
nil
{
return
0
}
return
num
}
func
StringsContains
(
strs
[]
string
,
str
string
)
bool
{
for
_
,
s
:=
range
strs
{
if
s
==
str
{
return
true
}
}
return
false
}
// StringToByteSlice []byte only read, panic on append
func
StringToByteSlice
(
s
string
)
[]
byte
{
tmp1
:=
(
*
[
2
]
uintptr
)(
unsafe
.
Pointer
(
&
s
))
tmp2
:=
[
3
]
uintptr
{
tmp1
[
0
],
tmp1
[
1
],
tmp1
[
1
]}
return
*
(
*
[]
byte
)(
unsafe
.
Pointer
(
&
tmp2
))
}
func
RandomSleep
()
{
func
RandomSleep
()
{
// Sleep for 0-3000 ms
// Sleep for 0-3000 ms
time
.
Sleep
(
time
.
Duration
(
rand
.
Intn
(
3000
))
*
time
.
Millisecond
)
time
.
Sleep
(
time
.
Duration
(
rand
.
Intn
(
3000
))
*
time
.
Millisecond
)
}
}
func
MapToJsonStr
(
m
map
[
string
]
interface
{})
string
{
bytes
,
err
:=
json
.
Marshal
(
m
)
if
err
!=
nil
{
return
""
}
return
string
(
bytes
)
}
func
MapToJsonStrFloat
(
m
map
[
string
]
float64
)
string
{
bytes
,
err
:=
json
.
Marshal
(
m
)
if
err
!=
nil
{
return
""
}
return
string
(
bytes
)
}
func
StrToMap
(
str
string
)
map
[
string
]
interface
{}
{
m
:=
make
(
map
[
string
]
interface
{})
err
:=
json
.
Unmarshal
([]
byte
(
str
),
&
m
)
if
err
!=
nil
{
return
nil
}
return
m
}
controller/channel-test.go
View file @
ee0e1c97
...
@@ -85,7 +85,7 @@ func testChannel(channel *model.Channel, testModel string) (err error, openAIErr
...
@@ -85,7 +85,7 @@ func testChannel(channel *model.Channel, testModel string) (err error, openAIErr
meta
.
UpstreamModelName
=
testModel
meta
.
UpstreamModelName
=
testModel
common
.
SysLog
(
fmt
.
Sprintf
(
"testing channel %d with model %s"
,
channel
.
Id
,
testModel
))
common
.
SysLog
(
fmt
.
Sprintf
(
"testing channel %d with model %s"
,
channel
.
Id
,
testModel
))
adaptor
.
Init
(
meta
,
*
request
)
adaptor
.
Init
(
meta
)
convertedRequest
,
err
:=
adaptor
.
ConvertRequest
(
c
,
meta
,
request
)
convertedRequest
,
err
:=
adaptor
.
ConvertRequest
(
c
,
meta
,
request
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
controller/model.go
View file @
ee0e1c97
...
@@ -131,7 +131,7 @@ func init() {
...
@@ -131,7 +131,7 @@ func init() {
}
}
meta
:=
&
relaycommon
.
RelayInfo
{
ChannelType
:
i
}
meta
:=
&
relaycommon
.
RelayInfo
{
ChannelType
:
i
}
adaptor
:=
relay
.
GetAdaptor
(
apiType
)
adaptor
:=
relay
.
GetAdaptor
(
apiType
)
adaptor
.
Init
(
meta
,
dto
.
GeneralOpenAIRequest
{}
)
adaptor
.
Init
(
meta
)
channelId2Models
[
i
]
=
adaptor
.
GetModelList
()
channelId2Models
[
i
]
=
adaptor
.
GetModelList
()
}
}
}
}
...
...
dto/audio.go
View file @
ee0e1c97
package
dto
package
dto
type
TextToSpeech
Request
struct
{
type
Audio
Request
struct
{
Model
string
`json:"model"
binding:"required"
`
Model
string
`json:"model"`
Input
string
`json:"input"
binding:"required"
`
Input
string
`json:"input"`
Voice
string
`json:"voice"
binding:"required"
`
Voice
string
`json:"voice"`
Speed
float64
`json:"speed"`
Speed
float64
`json:"speed
,omitempty
"`
ResponseFormat
string
`json:"response_format"`
ResponseFormat
string
`json:"response_format
,omitempty
"`
}
}
type
AudioResponse
struct
{
type
AudioResponse
struct
{
Text
string
`json:"text"`
Text
string
`json:"text"`
}
}
type
WhisperVerboseJSONResponse
struct
{
Task
string
`json:"task,omitempty"`
Language
string
`json:"language,omitempty"`
Duration
float64
`json:"duration,omitempty"`
Text
string
`json:"text,omitempty"`
Segments
[]
Segment
`json:"segments,omitempty"`
}
type
Segment
struct
{
Id
int
`json:"id"`
Seek
int
`json:"seek"`
Start
float64
`json:"start"`
End
float64
`json:"end"`
Text
string
`json:"text"`
Tokens
[]
int
`json:"tokens"`
Temperature
float64
`json:"temperature"`
AvgLogprob
float64
`json:"avg_logprob"`
CompressionRatio
float64
`json:"compression_ratio"`
NoSpeechProb
float64
`json:"no_speech_prob"`
}
middleware/distributor.go
View file @
ee0e1c97
...
@@ -154,18 +154,20 @@ func getModelRequest(c *gin.Context) (*ModelRequest, bool, error) {
...
@@ -154,18 +154,20 @@ func getModelRequest(c *gin.Context) (*ModelRequest, bool, error) {
}
}
}
}
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/images/generations"
)
{
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/images/generations"
)
{
if
modelRequest
.
Model
==
""
{
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
"dall-e"
)
modelRequest
.
Model
=
"dall-e"
}
}
}
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio"
)
{
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio"
)
{
if
modelRequest
.
Model
==
""
{
relayMode
:=
relayconstant
.
RelayModeAudioSpeech
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/speech"
)
{
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/speech"
)
{
modelRequest
.
Model
=
"tts-1"
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
"tts-1"
)
}
else
{
}
else
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/translations"
)
{
modelRequest
.
Model
=
"whisper-1"
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
"whisper-1"
)
}
relayMode
=
relayconstant
.
RelayModeAudioTranslation
}
else
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/transcriptions"
)
{
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
"whisper-1"
)
relayMode
=
relayconstant
.
RelayModeAudioTranscription
}
}
c
.
Set
(
"relay_mode"
,
relayMode
)
}
}
return
&
modelRequest
,
shouldSelectChannel
,
nil
return
&
modelRequest
,
shouldSelectChannel
,
nil
}
}
...
...
relay/channel/adapter.go
View file @
ee0e1c97
...
@@ -10,12 +10,13 @@ import (
...
@@ -10,12 +10,13 @@ import (
type
Adaptor
interface
{
type
Adaptor
interface
{
// Init IsStream bool
// Init IsStream bool
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
Init
(
info
*
relaycommon
.
RelayInfo
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
SetupRequestHeader
(
c
*
gin
.
Context
,
req
*
http
.
Request
,
info
*
relaycommon
.
RelayInfo
)
error
SetupRequestHeader
(
c
*
gin
.
Context
,
req
*
http
.
Request
,
info
*
relaycommon
.
RelayInfo
)
error
ConvertRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
*
dto
.
GeneralOpenAIRequest
)
(
any
,
error
)
ConvertRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
*
dto
.
GeneralOpenAIRequest
)
(
any
,
error
)
ConvertRerankRequest
(
c
*
gin
.
Context
,
relayMode
int
,
request
dto
.
RerankRequest
)
(
any
,
error
)
ConvertRerankRequest
(
c
*
gin
.
Context
,
relayMode
int
,
request
dto
.
RerankRequest
)
(
any
,
error
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
DoRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
requestBody
io
.
Reader
)
(
*
http
.
Response
,
error
)
DoRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
requestBody
io
.
Reader
)
(
*
http
.
Response
,
error
)
DoResponse
(
c
*
gin
.
Context
,
resp
*
http
.
Response
,
info
*
relaycommon
.
RelayInfo
)
(
usage
*
dto
.
Usage
,
err
*
dto
.
OpenAIErrorWithStatusCode
)
DoResponse
(
c
*
gin
.
Context
,
resp
*
http
.
Response
,
info
*
relaycommon
.
RelayInfo
)
(
usage
*
dto
.
Usage
,
err
*
dto
.
OpenAIErrorWithStatusCode
)
GetModelList
()
[]
string
GetModelList
()
[]
string
...
...
relay/channel/ali/adaptor.go
View file @
ee0e1c97
...
@@ -15,11 +15,17 @@ import (
...
@@ -15,11 +15,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/channel/api_request.go
View file @
ee0e1c97
...
@@ -7,14 +7,19 @@ import (
...
@@ -7,14 +7,19 @@ import (
"io"
"io"
"net/http"
"net/http"
"one-api/relay/common"
"one-api/relay/common"
"one-api/relay/constant"
"one-api/service"
"one-api/service"
)
)
func
SetupApiRequestHeader
(
info
*
common
.
RelayInfo
,
c
*
gin
.
Context
,
req
*
http
.
Request
)
{
func
SetupApiRequestHeader
(
info
*
common
.
RelayInfo
,
c
*
gin
.
Context
,
req
*
http
.
Request
)
{
req
.
Header
.
Set
(
"Content-Type"
,
c
.
Request
.
Header
.
Get
(
"Content-Type"
))
if
info
.
RelayMode
==
constant
.
RelayModeAudioTranscription
||
info
.
RelayMode
==
constant
.
RelayModeAudioTranslation
{
req
.
Header
.
Set
(
"Accept"
,
c
.
Request
.
Header
.
Get
(
"Accept"
))
// multipart/form-data
if
info
.
IsStream
&&
c
.
Request
.
Header
.
Get
(
"Accept"
)
==
""
{
}
else
{
req
.
Header
.
Set
(
"Accept"
,
"text/event-stream"
)
req
.
Header
.
Set
(
"Content-Type"
,
c
.
Request
.
Header
.
Get
(
"Content-Type"
))
req
.
Header
.
Set
(
"Accept"
,
c
.
Request
.
Header
.
Get
(
"Accept"
))
if
info
.
IsStream
&&
c
.
Request
.
Header
.
Get
(
"Accept"
)
==
""
{
req
.
Header
.
Set
(
"Accept"
,
"text/event-stream"
)
}
}
}
}
}
...
@@ -38,6 +43,29 @@ func DoApiRequest(a Adaptor, c *gin.Context, info *common.RelayInfo, requestBody
...
@@ -38,6 +43,29 @@ func DoApiRequest(a Adaptor, c *gin.Context, info *common.RelayInfo, requestBody
return
resp
,
nil
return
resp
,
nil
}
}
func
DoFormRequest
(
a
Adaptor
,
c
*
gin
.
Context
,
info
*
common
.
RelayInfo
,
requestBody
io
.
Reader
)
(
*
http
.
Response
,
error
)
{
fullRequestURL
,
err
:=
a
.
GetRequestURL
(
info
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"get request url failed: %w"
,
err
)
}
req
,
err
:=
http
.
NewRequest
(
c
.
Request
.
Method
,
fullRequestURL
,
requestBody
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"new request failed: %w"
,
err
)
}
// set form data
req
.
Header
.
Set
(
"Content-Type"
,
c
.
Request
.
Header
.
Get
(
"Content-Type"
))
err
=
a
.
SetupRequestHeader
(
c
,
req
,
info
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"setup request header failed: %w"
,
err
)
}
resp
,
err
:=
doRequest
(
c
,
req
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"do request failed: %w"
,
err
)
}
return
resp
,
nil
}
func
doRequest
(
c
*
gin
.
Context
,
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
func
doRequest
(
c
*
gin
.
Context
,
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
resp
,
err
:=
service
.
GetHttpClient
()
.
Do
(
req
)
resp
,
err
:=
service
.
GetHttpClient
()
.
Do
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
relay/channel/aws/adaptor.go
View file @
ee0e1c97
...
@@ -20,12 +20,17 @@ type Adaptor struct {
...
@@ -20,12 +20,17 @@ type Adaptor struct {
RequestMode
int
RequestMode
int
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
if
strings
.
HasPrefix
(
info
.
UpstreamModelName
,
"claude-3"
)
{
if
strings
.
HasPrefix
(
info
.
UpstreamModelName
,
"claude-3"
)
{
a
.
RequestMode
=
RequestModeMessage
a
.
RequestMode
=
RequestModeMessage
}
else
{
}
else
{
...
...
relay/channel/baidu/adaptor.go
View file @
ee0e1c97
...
@@ -16,12 +16,17 @@ import (
...
@@ -16,12 +16,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
...
...
relay/channel/claude/adaptor.go
View file @
ee0e1c97
...
@@ -21,12 +21,17 @@ type Adaptor struct {
...
@@ -21,12 +21,17 @@ type Adaptor struct {
RequestMode
int
RequestMode
int
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
if
strings
.
HasPrefix
(
info
.
UpstreamModelName
,
"claude-3"
)
{
if
strings
.
HasPrefix
(
info
.
UpstreamModelName
,
"claude-3"
)
{
a
.
RequestMode
=
RequestModeMessage
a
.
RequestMode
=
RequestModeMessage
}
else
{
}
else
{
...
...
relay/channel/cloudflare/adaptor.go
View file @
ee0e1c97
...
@@ -15,10 +15,17 @@ import (
...
@@ -15,10 +15,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/channel/cohere/adaptor.go
View file @
ee0e1c97
package
cohere
package
cohere
import
(
import
(
"errors"
"fmt"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin"
"io"
"io"
...
@@ -14,10 +15,17 @@ import (
...
@@ -14,10 +15,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/channel/dify/adaptor.go
View file @
ee0e1c97
...
@@ -14,12 +14,17 @@ import (
...
@@ -14,12 +14,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/channel/gemini/adaptor.go
View file @
ee0e1c97
...
@@ -14,10 +14,17 @@ import (
...
@@ -14,10 +14,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
// 定义一个映射,存储模型名称和对应的版本
// 定义一个映射,存储模型名称和对应的版本
...
...
relay/channel/jina/adaptor.go
View file @
ee0e1c97
...
@@ -15,10 +15,17 @@ import (
...
@@ -15,10 +15,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/channel/ollama/adaptor.go
View file @
ee0e1c97
...
@@ -15,10 +15,17 @@ import (
...
@@ -15,10 +15,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/channel/openai/adaptor.go
View file @
ee0e1c97
package
openai
package
openai
import
(
import
(
"bytes"
"encoding/json"
"errors"
"errors"
"fmt"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin"
"io"
"io"
"mime/multipart"
"net/http"
"net/http"
"one-api/common"
"one-api/common"
"one-api/dto"
"one-api/dto"
...
@@ -14,21 +17,16 @@ import (
...
@@ -14,21 +17,16 @@ import (
"one-api/relay/channel/minimax"
"one-api/relay/channel/minimax"
"one-api/relay/channel/moonshot"
"one-api/relay/channel/moonshot"
relaycommon
"one-api/relay/common"
relaycommon
"one-api/relay/common"
"one-api/relay/constant"
"strings"
"strings"
)
)
type
Adaptor
struct
{
type
Adaptor
struct
{
ChannelType
int
ChannelType
int
ResponseFormat
string
}
}
func
(
a
*
Adaptor
)
ConvertRerankRequest
(
c
*
gin
.
Context
,
relayMode
int
,
request
dto
.
RerankRequest
)
(
any
,
error
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
return
nil
,
nil
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
a
.
ChannelType
=
info
.
ChannelType
a
.
ChannelType
=
info
.
ChannelType
}
}
...
@@ -83,15 +81,73 @@ func (a *Adaptor) ConvertRequest(c *gin.Context, info *relaycommon.RelayInfo, re
...
@@ -83,15 +81,73 @@ func (a *Adaptor) ConvertRequest(c *gin.Context, info *relaycommon.RelayInfo, re
return
request
,
nil
return
request
,
nil
}
}
func
(
a
*
Adaptor
)
ConvertRerankRequest
(
c
*
gin
.
Context
,
relayMode
int
,
request
dto
.
RerankRequest
)
(
any
,
error
)
{
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
a
.
ResponseFormat
=
request
.
ResponseFormat
if
info
.
RelayMode
==
constant
.
RelayModeAudioSpeech
{
jsonData
,
err
:=
json
.
Marshal
(
request
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error marshalling object: %w"
,
err
)
}
return
bytes
.
NewReader
(
jsonData
),
nil
}
else
{
var
requestBody
bytes
.
Buffer
writer
:=
multipart
.
NewWriter
(
&
requestBody
)
writer
.
WriteField
(
"model"
,
request
.
Model
)
// 添加文件字段
file
,
header
,
err
:=
c
.
Request
.
FormFile
(
"file"
)
if
err
!=
nil
{
return
nil
,
errors
.
New
(
"file is required"
)
}
defer
file
.
Close
()
part
,
err
:=
writer
.
CreateFormFile
(
"file"
,
header
.
Filename
)
if
err
!=
nil
{
return
nil
,
errors
.
New
(
"create form file failed"
)
}
if
_
,
err
:=
io
.
Copy
(
part
,
file
);
err
!=
nil
{
return
nil
,
errors
.
New
(
"copy file failed"
)
}
// 关闭 multipart 编写器以设置分界线
writer
.
Close
()
c
.
Request
.
Header
.
Set
(
"Content-Type"
,
writer
.
FormDataContentType
())
return
&
requestBody
,
nil
}
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
DoRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
requestBody
io
.
Reader
)
(
*
http
.
Response
,
error
)
{
func
(
a
*
Adaptor
)
DoRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
requestBody
io
.
Reader
)
(
*
http
.
Response
,
error
)
{
return
channel
.
DoApiRequest
(
a
,
c
,
info
,
requestBody
)
if
info
.
RelayMode
==
constant
.
RelayModeAudioTranscription
||
info
.
RelayMode
==
constant
.
RelayModeAudioTranslation
{
return
channel
.
DoFormRequest
(
a
,
c
,
info
,
requestBody
)
}
else
{
return
channel
.
DoApiRequest
(
a
,
c
,
info
,
requestBody
)
}
}
}
func
(
a
*
Adaptor
)
DoResponse
(
c
*
gin
.
Context
,
resp
*
http
.
Response
,
info
*
relaycommon
.
RelayInfo
)
(
usage
*
dto
.
Usage
,
err
*
dto
.
OpenAIErrorWithStatusCode
)
{
func
(
a
*
Adaptor
)
DoResponse
(
c
*
gin
.
Context
,
resp
*
http
.
Response
,
info
*
relaycommon
.
RelayInfo
)
(
usage
*
dto
.
Usage
,
err
*
dto
.
OpenAIErrorWithStatusCode
)
{
if
info
.
IsStream
{
switch
info
.
RelayMode
{
err
,
usage
=
OpenaiStreamHandler
(
c
,
resp
,
info
)
case
constant
.
RelayModeAudioSpeech
:
}
else
{
err
,
usage
=
OpenaiTTSHandler
(
c
,
resp
,
info
)
err
,
usage
=
OpenaiHandler
(
c
,
resp
,
info
.
PromptTokens
,
info
.
UpstreamModelName
)
case
constant
.
RelayModeAudioTranslation
:
fallthrough
case
constant
.
RelayModeAudioTranscription
:
err
,
usage
=
OpenaiSTTHandler
(
c
,
resp
,
info
,
a
.
ResponseFormat
)
default
:
if
info
.
IsStream
{
err
,
usage
=
OpenaiStreamHandler
(
c
,
resp
,
info
)
}
else
{
err
,
usage
=
OpenaiHandler
(
c
,
resp
,
info
.
PromptTokens
,
info
.
UpstreamModelName
)
}
}
}
return
return
}
}
...
...
relay/channel/openai/relay-openai.go
View file @
ee0e1c97
...
@@ -4,6 +4,7 @@ import (
...
@@ -4,6 +4,7 @@ import (
"bufio"
"bufio"
"bytes"
"bytes"
"encoding/json"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin"
"io"
"io"
"net/http"
"net/http"
...
@@ -224,3 +225,139 @@ func OpenaiHandler(c *gin.Context, resp *http.Response, promptTokens int, model
...
@@ -224,3 +225,139 @@ func OpenaiHandler(c *gin.Context, resp *http.Response, promptTokens int, model
}
}
return
nil
,
&
simpleResponse
.
Usage
return
nil
,
&
simpleResponse
.
Usage
}
}
func
OpenaiTTSHandler
(
c
*
gin
.
Context
,
resp
*
http
.
Response
,
info
*
relaycommon
.
RelayInfo
)
(
*
dto
.
OpenAIErrorWithStatusCode
,
*
dto
.
Usage
)
{
responseBody
,
err
:=
io
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"read_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
err
=
resp
.
Body
.
Close
()
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"close_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
// Reset response body
resp
.
Body
=
io
.
NopCloser
(
bytes
.
NewBuffer
(
responseBody
))
// We shouldn't set the header before we parse the response body, because the parse part may fail.
// And then we will have to send an error response, but in this case, the header has already been set.
// So the httpClient will be confused by the response.
// For example, Postman will report error, and we cannot check the response at all.
for
k
,
v
:=
range
resp
.
Header
{
c
.
Writer
.
Header
()
.
Set
(
k
,
v
[
0
])
}
c
.
Writer
.
WriteHeader
(
resp
.
StatusCode
)
_
,
err
=
io
.
Copy
(
c
.
Writer
,
resp
.
Body
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"copy_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
err
=
resp
.
Body
.
Close
()
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"close_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
usage
:=
&
dto
.
Usage
{}
usage
.
PromptTokens
=
info
.
PromptTokens
usage
.
TotalTokens
=
info
.
PromptTokens
return
nil
,
usage
}
func
OpenaiSTTHandler
(
c
*
gin
.
Context
,
resp
*
http
.
Response
,
info
*
relaycommon
.
RelayInfo
,
responseFormat
string
)
(
*
dto
.
OpenAIErrorWithStatusCode
,
*
dto
.
Usage
)
{
var
audioResp
dto
.
AudioResponse
responseBody
,
err
:=
io
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"read_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
err
=
resp
.
Body
.
Close
()
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"close_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
err
=
json
.
Unmarshal
(
responseBody
,
&
audioResp
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"unmarshal_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
// Reset response body
resp
.
Body
=
io
.
NopCloser
(
bytes
.
NewBuffer
(
responseBody
))
// We shouldn't set the header before we parse the response body, because the parse part may fail.
// And then we will have to send an error response, but in this case, the header has already been set.
// So the httpClient will be confused by the response.
// For example, Postman will report error, and we cannot check the response at all.
for
k
,
v
:=
range
resp
.
Header
{
c
.
Writer
.
Header
()
.
Set
(
k
,
v
[
0
])
}
c
.
Writer
.
WriteHeader
(
resp
.
StatusCode
)
_
,
err
=
io
.
Copy
(
c
.
Writer
,
resp
.
Body
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"copy_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
err
=
resp
.
Body
.
Close
()
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"close_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
var
text
string
switch
responseFormat
{
case
"json"
:
text
,
err
=
getTextFromJSON
(
responseBody
)
case
"text"
:
text
,
err
=
getTextFromText
(
responseBody
)
case
"srt"
:
text
,
err
=
getTextFromSRT
(
responseBody
)
case
"verbose_json"
:
text
,
err
=
getTextFromVerboseJSON
(
responseBody
)
case
"vtt"
:
text
,
err
=
getTextFromVTT
(
responseBody
)
}
usage
:=
&
dto
.
Usage
{}
usage
.
PromptTokens
=
info
.
PromptTokens
usage
.
CompletionTokens
,
_
=
service
.
CountTokenText
(
text
,
info
.
UpstreamModelName
)
usage
.
TotalTokens
=
usage
.
PromptTokens
+
usage
.
CompletionTokens
return
nil
,
usage
}
func
getTextFromVTT
(
body
[]
byte
)
(
string
,
error
)
{
return
getTextFromSRT
(
body
)
}
func
getTextFromVerboseJSON
(
body
[]
byte
)
(
string
,
error
)
{
var
whisperResponse
dto
.
WhisperVerboseJSONResponse
if
err
:=
json
.
Unmarshal
(
body
,
&
whisperResponse
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"unmarshal_response_body_failed err :%w"
,
err
)
}
return
whisperResponse
.
Text
,
nil
}
func
getTextFromSRT
(
body
[]
byte
)
(
string
,
error
)
{
scanner
:=
bufio
.
NewScanner
(
strings
.
NewReader
(
string
(
body
)))
var
builder
strings
.
Builder
var
textLine
bool
for
scanner
.
Scan
()
{
line
:=
scanner
.
Text
()
if
textLine
{
builder
.
WriteString
(
line
)
textLine
=
false
continue
}
else
if
strings
.
Contains
(
line
,
"-->"
)
{
textLine
=
true
continue
}
}
if
err
:=
scanner
.
Err
();
err
!=
nil
{
return
""
,
err
}
return
builder
.
String
(),
nil
}
func
getTextFromText
(
body
[]
byte
)
(
string
,
error
)
{
return
strings
.
TrimSuffix
(
string
(
body
),
"
\n
"
),
nil
}
func
getTextFromJSON
(
body
[]
byte
)
(
string
,
error
)
{
var
whisperResponse
dto
.
AudioResponse
if
err
:=
json
.
Unmarshal
(
body
,
&
whisperResponse
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"unmarshal_response_body_failed err :%w"
,
err
)
}
return
whisperResponse
.
Text
,
nil
}
relay/channel/palm/adaptor.go
View file @
ee0e1c97
...
@@ -15,12 +15,17 @@ import (
...
@@ -15,12 +15,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/channel/perplexity/adaptor.go
View file @
ee0e1c97
...
@@ -15,12 +15,17 @@ import (
...
@@ -15,12 +15,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/channel/tencent/adaptor.go
View file @
ee0e1c97
...
@@ -23,12 +23,17 @@ type Adaptor struct {
...
@@ -23,12 +23,17 @@ type Adaptor struct {
Timestamp
int64
Timestamp
int64
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
a
.
Action
=
"ChatCompletions"
a
.
Action
=
"ChatCompletions"
a
.
Version
=
"2023-09-01"
a
.
Version
=
"2023-09-01"
a
.
Timestamp
=
common
.
GetTimestamp
()
a
.
Timestamp
=
common
.
GetTimestamp
()
...
...
relay/channel/xunfei/adaptor.go
View file @
ee0e1c97
...
@@ -16,12 +16,17 @@ type Adaptor struct {
...
@@ -16,12 +16,17 @@ type Adaptor struct {
request
*
dto
.
GeneralOpenAIRequest
request
*
dto
.
GeneralOpenAIRequest
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/channel/zhipu/adaptor.go
View file @
ee0e1c97
...
@@ -14,12 +14,17 @@ import (
...
@@ -14,12 +14,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/channel/zhipu_4v/adaptor.go
View file @
ee0e1c97
...
@@ -15,12 +15,17 @@ import (
...
@@ -15,12 +15,17 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
func
(
a
*
Adaptor
)
InitRerank
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
RerankRequest
)
{
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
//TODO implement me
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
,
request
dto
.
GeneralOpenAIRequest
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
func
(
a
*
Adaptor
)
GetRequestURL
(
info
*
relaycommon
.
RelayInfo
)
(
string
,
error
)
{
...
...
relay/constant/relay_mode.go
View file @
ee0e1c97
...
@@ -13,6 +13,7 @@ const (
...
@@ -13,6 +13,7 @@ const (
RelayModeModerations
RelayModeModerations
RelayModeImagesGenerations
RelayModeImagesGenerations
RelayModeEdits
RelayModeEdits
RelayModeMidjourneyImagine
RelayModeMidjourneyImagine
RelayModeMidjourneyDescribe
RelayModeMidjourneyDescribe
RelayModeMidjourneyBlend
RelayModeMidjourneyBlend
...
@@ -22,16 +23,19 @@ const (
...
@@ -22,16 +23,19 @@ const (
RelayModeMidjourneyTaskFetch
RelayModeMidjourneyTaskFetch
RelayModeMidjourneyTaskImageSeed
RelayModeMidjourneyTaskImageSeed
RelayModeMidjourneyTaskFetchByCondition
RelayModeMidjourneyTaskFetchByCondition
RelayModeAudioSpeech
RelayModeAudioTranscription
RelayModeAudioTranslation
RelayModeMidjourneyAction
RelayModeMidjourneyAction
RelayModeMidjourneyModal
RelayModeMidjourneyModal
RelayModeMidjourneyShorten
RelayModeMidjourneyShorten
RelayModeSwapFace
RelayModeSwapFace
RelayModeAudioSpeech
// tts
RelayModeAudioTranscription
// whisper
RelayModeAudioTranslation
// whisper
RelayModeSunoFetch
RelayModeSunoFetch
RelayModeSunoFetchByID
RelayModeSunoFetchByID
RelayModeSunoSubmit
RelayModeSunoSubmit
RelayModeRerank
RelayModeRerank
)
)
...
...
relay/relay-audio.go
View file @
ee0e1c97
package
relay
package
relay
import
(
import
(
"bytes"
"context"
"encoding/json"
"encoding/json"
"errors"
"errors"
"fmt"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin"
"io"
"net/http"
"net/http"
"one-api/common"
"one-api/common"
"one-api/constant"
"one-api/constant"
...
@@ -16,69 +13,71 @@ import (
...
@@ -16,69 +13,71 @@ import (
relaycommon
"one-api/relay/common"
relaycommon
"one-api/relay/common"
relayconstant
"one-api/relay/constant"
relayconstant
"one-api/relay/constant"
"one-api/service"
"one-api/service"
"strings"
"time"
)
)
func
AudioHelper
(
c
*
gin
.
Context
,
relayMode
int
)
*
dto
.
OpenAIErrorWithStatusCode
{
func
getAndValidAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
)
(
*
dto
.
AudioRequest
,
error
)
{
tokenId
:=
c
.
GetInt
(
"token_id"
)
audioRequest
:=
&
dto
.
AudioRequest
{}
channelType
:=
c
.
GetInt
(
"channel"
)
err
:=
common
.
UnmarshalBodyReusable
(
c
,
audioRequest
)
channelId
:=
c
.
GetInt
(
"channel_id"
)
if
err
!=
nil
{
userId
:=
c
.
GetInt
(
"id"
)
return
nil
,
err
group
:=
c
.
GetString
(
"group"
)
}
startTime
:=
time
.
Now
()
switch
info
.
RelayMode
{
case
relayconstant
.
RelayModeAudioSpeech
:
var
audioRequest
dto
.
TextToSpeechRequest
if
audioRequest
.
Model
==
""
{
if
!
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/transcriptions"
)
{
return
nil
,
errors
.
New
(
"model is required"
)
err
:=
common
.
UnmarshalBodyReusable
(
c
,
&
audioRequest
)
}
if
err
!=
nil
{
if
constant
.
ShouldCheckPromptSensitive
()
{
return
service
.
OpenAIErrorWrapper
(
err
,
"bind_request_body_failed"
,
http
.
StatusBadRequest
)
err
:=
service
.
CheckSensitiveInput
(
audioRequest
.
Input
)
if
err
!=
nil
{
return
nil
,
err
}
}
default
:
if
audioRequest
.
Model
==
""
{
audioRequest
.
Model
=
c
.
PostForm
(
"model"
)
}
}
}
else
{
if
audioRequest
.
Model
==
""
{
audioRequest
=
dto
.
TextToSpeechRequest
{
return
nil
,
errors
.
New
(
"model is required"
)
Model
:
"whisper-1"
,
}
if
audioRequest
.
ResponseFormat
==
""
{
audioRequest
.
ResponseFormat
=
"json"
}
}
}
}
//err := common.UnmarshalBodyReusable(c, &audioRequest)
return
audioRequest
,
nil
}
// request validation
func
AudioHelper
(
c
*
gin
.
Context
,
relayMode
int
)
*
dto
.
OpenAIErrorWithStatusCode
{
if
audioRequest
.
Model
==
""
{
relayInfo
:=
relaycommon
.
GenRelayInfo
(
c
)
return
service
.
OpenAIErrorWrapper
(
errors
.
New
(
"model is required"
),
"required_field_missing"
,
http
.
StatusBadRequest
)
audioRequest
,
err
:=
getAndValidAudioRequest
(
c
,
relayInfo
)
}
if
strings
.
HasPrefix
(
audioRequest
.
Model
,
"tts-1"
)
{
if
err
!=
nil
{
if
audioRequest
.
Voice
==
""
{
common
.
LogError
(
c
,
fmt
.
Sprintf
(
"getAndValidAudioRequest failed: %s"
,
err
.
Error
()))
return
service
.
OpenAIErrorWrapper
(
errors
.
New
(
"voice is required"
),
"required_field_missing"
,
http
.
StatusBadRequest
)
return
service
.
OpenAIErrorWrapper
(
err
,
"invalid_audio_request"
,
http
.
StatusBadRequest
)
}
}
}
var
err
error
promptTokens
:=
0
promptTokens
:=
0
preConsumedTokens
:=
common
.
PreConsumedQuota
preConsumedTokens
:=
common
.
PreConsumedQuota
if
strings
.
HasPrefix
(
audioRequest
.
Model
,
"tts-1"
)
{
if
relayInfo
.
RelayMode
==
relayconstant
.
RelayModeAudioSpeech
{
if
constant
.
ShouldCheckPromptSensitive
()
{
err
=
service
.
CheckSensitiveInput
(
audioRequest
.
Input
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"sensitive_words_detected"
,
http
.
StatusBadRequest
)
}
}
promptTokens
,
err
=
service
.
CountAudioToken
(
audioRequest
.
Input
,
audioRequest
.
Model
)
promptTokens
,
err
=
service
.
CountAudioToken
(
audioRequest
.
Input
,
audioRequest
.
Model
)
if
err
!=
nil
{
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"count_audio_token_failed"
,
http
.
StatusInternalServerError
)
return
service
.
OpenAIErrorWrapper
(
err
,
"count_audio_token_failed"
,
http
.
StatusInternalServerError
)
}
}
preConsumedTokens
=
promptTokens
preConsumedTokens
=
promptTokens
relayInfo
.
PromptTokens
=
promptTokens
}
}
modelRatio
:=
common
.
GetModelRatio
(
audioRequest
.
Model
)
modelRatio
:=
common
.
GetModelRatio
(
audioRequest
.
Model
)
groupRatio
:=
common
.
GetGroupRatio
(
g
roup
)
groupRatio
:=
common
.
GetGroupRatio
(
relayInfo
.
G
roup
)
ratio
:=
modelRatio
*
groupRatio
ratio
:=
modelRatio
*
groupRatio
preConsumedQuota
:=
int
(
float64
(
preConsumedTokens
)
*
ratio
)
preConsumedQuota
:=
int
(
float64
(
preConsumedTokens
)
*
ratio
)
userQuota
,
err
:=
model
.
CacheGetUserQuota
(
u
serId
)
userQuota
,
err
:=
model
.
CacheGetUserQuota
(
relayInfo
.
U
serId
)
if
err
!=
nil
{
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapperLocal
(
err
,
"get_user_quota_failed"
,
http
.
StatusInternalServerError
)
return
service
.
OpenAIErrorWrapperLocal
(
err
,
"get_user_quota_failed"
,
http
.
StatusInternalServerError
)
}
}
if
userQuota
-
preConsumedQuota
<
0
{
if
userQuota
-
preConsumedQuota
<
0
{
return
service
.
OpenAIErrorWrapperLocal
(
errors
.
New
(
"user quota is not enough"
),
"insufficient_user_quota"
,
http
.
StatusForbidden
)
return
service
.
OpenAIErrorWrapperLocal
(
errors
.
New
(
"user quota is not enough"
),
"insufficient_user_quota"
,
http
.
StatusForbidden
)
}
}
err
=
model
.
CacheDecreaseUserQuota
(
u
serId
,
preConsumedQuota
)
err
=
model
.
CacheDecreaseUserQuota
(
relayInfo
.
U
serId
,
preConsumedQuota
)
if
err
!=
nil
{
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapperLocal
(
err
,
"decrease_user_quota_failed"
,
http
.
StatusInternalServerError
)
return
service
.
OpenAIErrorWrapperLocal
(
err
,
"decrease_user_quota_failed"
,
http
.
StatusInternalServerError
)
}
}
...
@@ -88,28 +87,12 @@ func AudioHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusCode {
...
@@ -88,28 +87,12 @@ func AudioHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusCode {
preConsumedQuota
=
0
preConsumedQuota
=
0
}
}
if
preConsumedQuota
>
0
{
if
preConsumedQuota
>
0
{
userQuota
,
err
=
model
.
PreConsumeTokenQuota
(
t
okenId
,
preConsumedQuota
)
userQuota
,
err
=
model
.
PreConsumeTokenQuota
(
relayInfo
.
T
okenId
,
preConsumedQuota
)
if
err
!=
nil
{
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapperLocal
(
err
,
"pre_consume_token_quota_failed"
,
http
.
StatusForbidden
)
return
service
.
OpenAIErrorWrapperLocal
(
err
,
"pre_consume_token_quota_failed"
,
http
.
StatusForbidden
)
}
}
}
}
succeed
:=
false
defer
func
()
{
if
succeed
{
return
}
if
preConsumedQuota
>
0
{
// we need to roll back the pre-consumed quota
defer
func
()
{
go
func
()
{
// negative means add quota back for token & user
returnPreConsumedQuota
(
c
,
tokenId
,
userQuota
,
preConsumedQuota
)
}()
}()
}
}()
// map model name
// map model name
modelMapping
:=
c
.
GetString
(
"model_mapping"
)
modelMapping
:=
c
.
GetString
(
"model_mapping"
)
if
modelMapping
!=
""
{
if
modelMapping
!=
""
{
...
@@ -123,132 +106,42 @@ func AudioHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusCode {
...
@@ -123,132 +106,42 @@ func AudioHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusCode {
}
}
}
}
baseURL
:=
common
.
ChannelBaseURLs
[
channelType
]
adaptor
:=
GetAdaptor
(
relayInfo
.
ApiType
)
requestURL
:=
c
.
Request
.
URL
.
String
()
if
adaptor
==
nil
{
if
c
.
GetString
(
"base_url"
)
!=
""
{
return
service
.
OpenAIErrorWrapperLocal
(
fmt
.
Errorf
(
"invalid api type: %d"
,
relayInfo
.
ApiType
),
"invalid_api_type"
,
http
.
StatusBadRequest
)
baseURL
=
c
.
GetString
(
"base_url"
)
}
fullRequestURL
:=
relaycommon
.
GetFullRequestURL
(
baseURL
,
requestURL
,
channelType
)
if
relayMode
==
relayconstant
.
RelayModeAudioTranscription
&&
channelType
==
common
.
ChannelTypeAzure
{
// https://learn.microsoft.com/en-us/azure/ai-services/openai/whisper-quickstart?tabs=command-line#rest-api
apiVersion
:=
relaycommon
.
GetAPIVersion
(
c
)
fullRequestURL
=
fmt
.
Sprintf
(
"%s/openai/deployments/%s/audio/transcriptions?api-version=%s"
,
baseURL
,
audioRequest
.
Model
,
apiVersion
)
}
}
adaptor
.
Init
(
relayInfo
)
requestBody
:=
c
.
Request
.
Body
ioReader
,
err
:=
adaptor
.
ConvertAudioRequest
(
c
,
relayInfo
,
*
audioRequest
)
req
,
err
:=
http
.
NewRequest
(
c
.
Request
.
Method
,
fullRequestURL
,
requestBody
)
if
err
!=
nil
{
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"new
_request_failed"
,
http
.
StatusInternalServerError
)
return
service
.
OpenAIErrorWrapper
Local
(
err
,
"convert
_request_failed"
,
http
.
StatusInternalServerError
)
}
}
if
relayMode
==
relayconstant
.
RelayModeAudioTranscription
&&
channelType
==
common
.
ChannelTypeAzure
{
resp
,
err
:=
adaptor
.
DoRequest
(
c
,
relayInfo
,
ioReader
)
// https://learn.microsoft.com/en-us/azure/ai-services/openai/whisper-quickstart?tabs=command-line#rest-api
apiKey
:=
c
.
Request
.
Header
.
Get
(
"Authorization"
)
apiKey
=
strings
.
TrimPrefix
(
apiKey
,
"Bearer "
)
req
.
Header
.
Set
(
"api-key"
,
apiKey
)
req
.
ContentLength
=
c
.
Request
.
ContentLength
}
else
{
req
.
Header
.
Set
(
"Authorization"
,
c
.
Request
.
Header
.
Get
(
"Authorization"
))
}
req
.
Header
.
Set
(
"Content-Type"
,
c
.
Request
.
Header
.
Get
(
"Content-Type"
))
req
.
Header
.
Set
(
"Accept"
,
c
.
Request
.
Header
.
Get
(
"Accept"
))
resp
,
err
:=
service
.
GetHttpClient
()
.
Do
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"do_request_failed"
,
http
.
StatusInternalServerError
)
return
service
.
OpenAIErrorWrapper
(
err
,
"do_request_failed"
,
http
.
StatusInternalServerError
)
}
}
err
=
req
.
Body
.
Close
()
statusCodeMappingStr
:=
c
.
GetString
(
"status_code_mapping"
)
if
err
!=
nil
{
if
resp
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"close_request_body_failed"
,
http
.
StatusInternalServerError
)
if
resp
.
StatusCode
!=
http
.
StatusOK
{
}
returnPreConsumedQuota
(
c
,
relayInfo
.
TokenId
,
userQuota
,
preConsumedQuota
)
err
=
c
.
Request
.
Body
.
Close
()
openaiErr
:=
service
.
RelayErrorHandler
(
resp
)
if
err
!=
nil
{
// reset status code 重置状态码
return
service
.
OpenAIErrorWrapper
(
err
,
"close_request_body_failed"
,
http
.
StatusInternalServerError
)
service
.
ResetStatusCode
(
openaiErr
,
statusCodeMappingStr
)
}
return
openaiErr
if
resp
.
StatusCode
!=
http
.
StatusOK
{
return
relaycommon
.
RelayErrorHandler
(
resp
)
}
succeed
=
true
var
audioResponse
dto
.
AudioResponse
defer
func
(
ctx
context
.
Context
)
{
go
func
()
{
useTimeSeconds
:=
time
.
Now
()
.
Unix
()
-
startTime
.
Unix
()
quota
:=
0
if
strings
.
HasPrefix
(
audioRequest
.
Model
,
"tts-1"
)
{
quota
=
promptTokens
}
else
{
quota
,
err
=
service
.
CountAudioToken
(
audioResponse
.
Text
,
audioRequest
.
Model
)
}
quota
=
int
(
float64
(
quota
)
*
ratio
)
if
ratio
!=
0
&&
quota
<=
0
{
quota
=
1
}
quotaDelta
:=
quota
-
preConsumedQuota
err
:=
model
.
PostConsumeTokenQuota
(
tokenId
,
userQuota
,
quotaDelta
,
preConsumedQuota
,
true
)
if
err
!=
nil
{
common
.
SysError
(
"error consuming token remain quota: "
+
err
.
Error
())
}
err
=
model
.
CacheUpdateUserQuota
(
userId
)
if
err
!=
nil
{
common
.
SysError
(
"error update user quota cache: "
+
err
.
Error
())
}
if
quota
!=
0
{
tokenName
:=
c
.
GetString
(
"token_name"
)
logContent
:=
fmt
.
Sprintf
(
"模型倍率 %.2f,分组倍率 %.2f"
,
modelRatio
,
groupRatio
)
other
:=
make
(
map
[
string
]
interface
{})
other
[
"model_ratio"
]
=
modelRatio
other
[
"group_ratio"
]
=
groupRatio
model
.
RecordConsumeLog
(
ctx
,
userId
,
channelId
,
promptTokens
,
0
,
audioRequest
.
Model
,
tokenName
,
quota
,
logContent
,
tokenId
,
userQuota
,
int
(
useTimeSeconds
),
false
,
other
)
model
.
UpdateUserUsedQuotaAndRequestCount
(
userId
,
quota
)
channelId
:=
c
.
GetInt
(
"channel_id"
)
model
.
UpdateChannelUsedQuota
(
channelId
,
quota
)
}
}()
}(
c
.
Request
.
Context
())
responseBody
,
err
:=
io
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"read_response_body_failed"
,
http
.
StatusInternalServerError
)
}
err
=
resp
.
Body
.
Close
()
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"close_response_body_failed"
,
http
.
StatusInternalServerError
)
}
if
strings
.
HasPrefix
(
audioRequest
.
Model
,
"tts-1"
)
{
}
else
{
err
=
json
.
Unmarshal
(
responseBody
,
&
audioResponse
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"unmarshal_response_body_failed"
,
http
.
StatusInternalServerError
)
}
contains
,
words
:=
service
.
SensitiveWordContains
(
audioResponse
.
Text
)
if
contains
{
return
service
.
OpenAIErrorWrapper
(
errors
.
New
(
"response contains sensitive words: "
+
strings
.
Join
(
words
,
", "
)),
"response_contains_sensitive_words"
,
http
.
StatusBadRequest
)
}
}
}
}
resp
.
Body
=
io
.
NopCloser
(
bytes
.
NewBuffer
(
responseBody
))
usage
,
openaiErr
:=
adaptor
.
DoResponse
(
c
,
resp
,
relayInfo
)
if
openaiErr
!=
nil
{
for
k
,
v
:=
range
resp
.
Header
{
returnPreConsumedQuota
(
c
,
relayInfo
.
TokenId
,
userQuota
,
preConsumedQuota
)
c
.
Writer
.
Header
()
.
Set
(
k
,
v
[
0
])
// reset status code 重置状态码
service
.
ResetStatusCode
(
openaiErr
,
statusCodeMappingStr
)
return
openaiErr
}
}
c
.
Writer
.
WriteHeader
(
resp
.
StatusCode
)
_
,
err
=
io
.
Copy
(
c
.
Writer
,
resp
.
Body
)
postConsumeQuota
(
c
,
relayInfo
,
audioRequest
.
Model
,
usage
,
ratio
,
preConsumedQuota
,
userQuota
,
modelRatio
,
groupRatio
,
0
,
false
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"copy_response_body_failed"
,
http
.
StatusInternalServerError
)
}
err
=
resp
.
Body
.
Close
()
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"close_response_body_failed"
,
http
.
StatusInternalServerError
)
}
return
nil
return
nil
}
}
relay/relay-text.go
View file @
ee0e1c97
...
@@ -91,7 +91,7 @@ func TextHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
...
@@ -91,7 +91,7 @@ func TextHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
}
}
}
}
relayInfo
.
UpstreamModelName
=
textRequest
.
Model
relayInfo
.
UpstreamModelName
=
textRequest
.
Model
modelPrice
,
s
uccess
:=
common
.
GetModelPrice
(
textRequest
.
Model
,
false
)
modelPrice
,
getModelPriceS
uccess
:=
common
.
GetModelPrice
(
textRequest
.
Model
,
false
)
groupRatio
:=
common
.
GetGroupRatio
(
relayInfo
.
Group
)
groupRatio
:=
common
.
GetGroupRatio
(
relayInfo
.
Group
)
var
preConsumedQuota
int
var
preConsumedQuota
int
...
@@ -112,7 +112,7 @@ func TextHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
...
@@ -112,7 +112,7 @@ func TextHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
return
service
.
OpenAIErrorWrapper
(
err
,
"count_token_messages_failed"
,
http
.
StatusInternalServerError
)
return
service
.
OpenAIErrorWrapper
(
err
,
"count_token_messages_failed"
,
http
.
StatusInternalServerError
)
}
}
if
!
s
uccess
{
if
!
getModelPriceS
uccess
{
preConsumedTokens
:=
common
.
PreConsumedQuota
preConsumedTokens
:=
common
.
PreConsumedQuota
if
textRequest
.
MaxTokens
!=
0
{
if
textRequest
.
MaxTokens
!=
0
{
preConsumedTokens
=
promptTokens
+
int
(
textRequest
.
MaxTokens
)
preConsumedTokens
=
promptTokens
+
int
(
textRequest
.
MaxTokens
)
...
@@ -150,7 +150,7 @@ func TextHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
...
@@ -150,7 +150,7 @@ func TextHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
if
adaptor
==
nil
{
if
adaptor
==
nil
{
return
service
.
OpenAIErrorWrapperLocal
(
fmt
.
Errorf
(
"invalid api type: %d"
,
relayInfo
.
ApiType
),
"invalid_api_type"
,
http
.
StatusBadRequest
)
return
service
.
OpenAIErrorWrapperLocal
(
fmt
.
Errorf
(
"invalid api type: %d"
,
relayInfo
.
ApiType
),
"invalid_api_type"
,
http
.
StatusBadRequest
)
}
}
adaptor
.
Init
(
relayInfo
,
*
textRequest
)
adaptor
.
Init
(
relayInfo
)
var
requestBody
io
.
Reader
var
requestBody
io
.
Reader
convertedRequest
,
err
:=
adaptor
.
ConvertRequest
(
c
,
relayInfo
,
textRequest
)
convertedRequest
,
err
:=
adaptor
.
ConvertRequest
(
c
,
relayInfo
,
textRequest
)
...
@@ -187,7 +187,7 @@ func TextHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
...
@@ -187,7 +187,7 @@ func TextHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
service
.
ResetStatusCode
(
openaiErr
,
statusCodeMappingStr
)
service
.
ResetStatusCode
(
openaiErr
,
statusCodeMappingStr
)
return
openaiErr
return
openaiErr
}
}
postConsumeQuota
(
c
,
relayInfo
,
textRequest
.
Model
,
usage
,
ratio
,
preConsumedQuota
,
userQuota
,
modelRatio
,
groupRatio
,
modelPrice
,
s
uccess
)
postConsumeQuota
(
c
,
relayInfo
,
textRequest
.
Model
,
usage
,
ratio
,
preConsumedQuota
,
userQuota
,
modelRatio
,
groupRatio
,
modelPrice
,
getModelPriceS
uccess
)
return
nil
return
nil
}
}
...
...
relay/relay_rerank.go
View file @
ee0e1c97
...
@@ -66,7 +66,7 @@ func RerankHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusCode
...
@@ -66,7 +66,7 @@ func RerankHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusCode
if
adaptor
==
nil
{
if
adaptor
==
nil
{
return
service
.
OpenAIErrorWrapperLocal
(
fmt
.
Errorf
(
"invalid api type: %d"
,
relayInfo
.
ApiType
),
"invalid_api_type"
,
http
.
StatusBadRequest
)
return
service
.
OpenAIErrorWrapperLocal
(
fmt
.
Errorf
(
"invalid api type: %d"
,
relayInfo
.
ApiType
),
"invalid_api_type"
,
http
.
StatusBadRequest
)
}
}
adaptor
.
Init
Rerank
(
relayInfo
,
*
rerankRequest
)
adaptor
.
Init
(
relayInfo
)
convertedRequest
,
err
:=
adaptor
.
ConvertRerankRequest
(
c
,
relayInfo
.
RelayMode
,
*
rerankRequest
)
convertedRequest
,
err
:=
adaptor
.
ConvertRerankRequest
(
c
,
relayInfo
.
RelayMode
,
*
rerankRequest
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment