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
1d4ebe39
authored
Jul 16, 2024
by
CalciumIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: support cloudflare audio
parent
ee0e1c97
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
90 additions
and
68 deletions
+90
-68
controller/channel-test.go
+1
-1
middleware/distributor.go
+2
-0
relay/channel/cloudflare/adaptor.go
+36
-14
relay/channel/cloudflare/dto.go
+8
-0
relay/channel/cloudflare/relay_cloudflare.go
+35
-0
relay/channel/openai/relay-openai.go
+3
-15
relay/common/relay_utils.go
+0
-33
relay/relay-audio.go
+1
-0
relay/relay-image.go
+1
-1
service/error.go
+3
-4
No files found.
controller/channel-test.go
View file @
1d4ebe39
...
@@ -102,7 +102,7 @@ func testChannel(channel *model.Channel, testModel string) (err error, openAIErr
...
@@ -102,7 +102,7 @@ func testChannel(channel *model.Channel, testModel string) (err error, openAIErr
return
err
,
nil
return
err
,
nil
}
}
if
resp
!=
nil
&&
resp
.
StatusCode
!=
http
.
StatusOK
{
if
resp
!=
nil
&&
resp
.
StatusCode
!=
http
.
StatusOK
{
err
:=
relaycommon
.
RelayErrorHandler
(
resp
)
err
:=
service
.
RelayErrorHandler
(
resp
)
return
fmt
.
Errorf
(
"status code %d: %s"
,
resp
.
StatusCode
,
err
.
Error
.
Message
),
err
return
fmt
.
Errorf
(
"status code %d: %s"
,
resp
.
StatusCode
,
err
.
Error
.
Message
),
err
}
}
usage
,
respErr
:=
adaptor
.
DoResponse
(
c
,
resp
,
meta
)
usage
,
respErr
:=
adaptor
.
DoResponse
(
c
,
resp
,
meta
)
...
...
middleware/distributor.go
View file @
1d4ebe39
...
@@ -161,9 +161,11 @@ func getModelRequest(c *gin.Context) (*ModelRequest, bool, error) {
...
@@ -161,9 +161,11 @@ func getModelRequest(c *gin.Context) (*ModelRequest, bool, error) {
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/speech"
)
{
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/speech"
)
{
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
"tts-1"
)
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
"tts-1"
)
}
else
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/translations"
)
{
}
else
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/translations"
)
{
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
c
.
PostForm
(
"model"
))
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
"whisper-1"
)
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
"whisper-1"
)
relayMode
=
relayconstant
.
RelayModeAudioTranslation
relayMode
=
relayconstant
.
RelayModeAudioTranslation
}
else
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/transcriptions"
)
{
}
else
if
strings
.
HasPrefix
(
c
.
Request
.
URL
.
Path
,
"/v1/audio/transcriptions"
)
{
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
c
.
PostForm
(
"model"
))
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
"whisper-1"
)
modelRequest
.
Model
=
common
.
GetStringIfEmpty
(
modelRequest
.
Model
,
"whisper-1"
)
relayMode
=
relayconstant
.
RelayModeAudioTranscription
relayMode
=
relayconstant
.
RelayModeAudioTranscription
}
}
...
...
relay/channel/cloudflare/adaptor.go
View file @
1d4ebe39
package
cloudflare
package
cloudflare
import
(
import
(
"bytes"
"errors"
"errors"
"fmt"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin"
...
@@ -15,16 +16,6 @@ import (
...
@@ -15,16 +16,6 @@ import (
type
Adaptor
struct
{
type
Adaptor
struct
{
}
}
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
)
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
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
}
}
...
@@ -65,11 +56,42 @@ func (a *Adaptor) ConvertRerankRequest(c *gin.Context, relayMode int, request dt
...
@@ -65,11 +56,42 @@ func (a *Adaptor) ConvertRerankRequest(c *gin.Context, relayMode int, request dt
return
request
,
nil
return
request
,
nil
}
}
func
(
a
*
Adaptor
)
ConvertAudioRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
AudioRequest
)
(
io
.
Reader
,
error
)
{
// 添加文件字段
file
,
_
,
err
:=
c
.
Request
.
FormFile
(
"file"
)
if
err
!=
nil
{
return
nil
,
errors
.
New
(
"file is required"
)
}
defer
file
.
Close
()
// 打开临时文件用于保存上传的文件内容
requestBody
:=
&
bytes
.
Buffer
{}
// 将上传的文件内容复制到临时文件
if
_
,
err
:=
io
.
Copy
(
requestBody
,
file
);
err
!=
nil
{
return
nil
,
err
}
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
)
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
=
cfStreamHandler
(
c
,
resp
,
info
)
case
constant
.
RelayModeEmbeddings
:
}
else
{
fallthrough
err
,
usage
=
cfHandler
(
c
,
resp
,
info
)
case
constant
.
RelayModeChatCompletions
:
if
info
.
IsStream
{
err
,
usage
=
cfStreamHandler
(
c
,
resp
,
info
)
}
else
{
err
,
usage
=
cfHandler
(
c
,
resp
,
info
)
}
case
constant
.
RelayModeAudioTranslation
:
fallthrough
case
constant
.
RelayModeAudioTranscription
:
err
,
usage
=
cfSTTHandler
(
c
,
resp
,
info
)
}
}
return
return
}
}
...
...
relay/channel/cloudflare/
model
.go
→
relay/channel/cloudflare/
dto
.go
View file @
1d4ebe39
...
@@ -11,3 +11,11 @@ type CfRequest struct {
...
@@ -11,3 +11,11 @@ type CfRequest struct {
Stream
bool
`json:"stream,omitempty"`
Stream
bool
`json:"stream,omitempty"`
Temperature
float64
`json:"temperature,omitempty"`
Temperature
float64
`json:"temperature,omitempty"`
}
}
type
CfAudioResponse
struct
{
Result
CfSTTResult
`json:"result"`
}
type
CfSTTResult
struct
{
Text
string
`json:"text"`
}
relay/channel/cloudflare/relay_cloudflare.go
View file @
1d4ebe39
...
@@ -119,3 +119,38 @@ func cfHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo)
...
@@ -119,3 +119,38 @@ func cfHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo)
_
,
_
=
c
.
Writer
.
Write
(
jsonResponse
)
_
,
_
=
c
.
Writer
.
Write
(
jsonResponse
)
return
nil
,
usage
return
nil
,
usage
}
}
func
cfSTTHandler
(
c
*
gin
.
Context
,
resp
*
http
.
Response
,
info
*
relaycommon
.
RelayInfo
)
(
*
dto
.
OpenAIErrorWithStatusCode
,
*
dto
.
Usage
)
{
var
cfResp
CfAudioResponse
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
,
&
cfResp
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"unmarshal_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
audioResp
:=
&
dto
.
AudioResponse
{
Text
:
cfResp
.
Result
.
Text
,
}
jsonResponse
,
err
:=
json
.
Marshal
(
audioResp
)
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"marshal_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
c
.
Writer
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
c
.
Writer
.
WriteHeader
(
resp
.
StatusCode
)
_
,
_
=
c
.
Writer
.
Write
(
jsonResponse
)
usage
:=
&
dto
.
Usage
{}
usage
.
PromptTokens
=
info
.
PromptTokens
usage
.
CompletionTokens
,
_
=
service
.
CountTokenText
(
cfResp
.
Result
.
Text
,
info
.
UpstreamModelName
)
usage
.
TotalTokens
=
usage
.
PromptTokens
+
usage
.
CompletionTokens
return
nil
,
usage
}
relay/channel/openai/relay-openai.go
View file @
1d4ebe39
...
@@ -165,10 +165,7 @@ func OpenaiStreamHandler(c *gin.Context, resp *http.Response, info *relaycommon.
...
@@ -165,10 +165,7 @@ func OpenaiStreamHandler(c *gin.Context, resp *http.Response, info *relaycommon.
service
.
Done
(
c
)
service
.
Done
(
c
)
err
:=
resp
.
Body
.
Close
()
resp
.
Body
.
Close
()
if
err
!=
nil
{
common
.
LogError
(
c
,
"close_response_body_failed: "
+
err
.
Error
())
}
return
nil
,
usage
return
nil
,
usage
}
}
...
@@ -206,11 +203,7 @@ func OpenaiHandler(c *gin.Context, resp *http.Response, promptTokens int, model
...
@@ -206,11 +203,7 @@ func OpenaiHandler(c *gin.Context, resp *http.Response, promptTokens int, model
if
err
!=
nil
{
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"copy_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
return
service
.
OpenAIErrorWrapper
(
err
,
"copy_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
}
err
=
resp
.
Body
.
Close
()
resp
.
Body
.
Close
()
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"close_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
if
simpleResponse
.
Usage
.
TotalTokens
==
0
||
(
simpleResponse
.
Usage
.
PromptTokens
==
0
&&
simpleResponse
.
Usage
.
CompletionTokens
==
0
)
{
if
simpleResponse
.
Usage
.
TotalTokens
==
0
||
(
simpleResponse
.
Usage
.
PromptTokens
==
0
&&
simpleResponse
.
Usage
.
CompletionTokens
==
0
)
{
completionTokens
:=
0
completionTokens
:=
0
for
_
,
choice
:=
range
simpleResponse
.
Choices
{
for
_
,
choice
:=
range
simpleResponse
.
Choices
{
...
@@ -257,7 +250,6 @@ func OpenaiTTSHandler(c *gin.Context, resp *http.Response, info *relaycommon.Rel
...
@@ -257,7 +250,6 @@ func OpenaiTTSHandler(c *gin.Context, resp *http.Response, info *relaycommon.Rel
usage
:=
&
dto
.
Usage
{}
usage
:=
&
dto
.
Usage
{}
usage
.
PromptTokens
=
info
.
PromptTokens
usage
.
PromptTokens
=
info
.
PromptTokens
usage
.
TotalTokens
=
info
.
PromptTokens
usage
.
TotalTokens
=
info
.
PromptTokens
return
nil
,
usage
return
nil
,
usage
}
}
...
@@ -290,10 +282,7 @@ func OpenaiSTTHandler(c *gin.Context, resp *http.Response, info *relaycommon.Rel
...
@@ -290,10 +282,7 @@ func OpenaiSTTHandler(c *gin.Context, resp *http.Response, info *relaycommon.Rel
if
err
!=
nil
{
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"copy_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
return
service
.
OpenAIErrorWrapper
(
err
,
"copy_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
}
err
=
resp
.
Body
.
Close
()
resp
.
Body
.
Close
()
if
err
!=
nil
{
return
service
.
OpenAIErrorWrapper
(
err
,
"close_response_body_failed"
,
http
.
StatusInternalServerError
),
nil
}
var
text
string
var
text
string
switch
responseFormat
{
switch
responseFormat
{
...
@@ -313,7 +302,6 @@ func OpenaiSTTHandler(c *gin.Context, resp *http.Response, info *relaycommon.Rel
...
@@ -313,7 +302,6 @@ func OpenaiSTTHandler(c *gin.Context, resp *http.Response, info *relaycommon.Rel
usage
.
PromptTokens
=
info
.
PromptTokens
usage
.
PromptTokens
=
info
.
PromptTokens
usage
.
CompletionTokens
,
_
=
service
.
CountTokenText
(
text
,
info
.
UpstreamModelName
)
usage
.
CompletionTokens
,
_
=
service
.
CountTokenText
(
text
,
info
.
UpstreamModelName
)
usage
.
TotalTokens
=
usage
.
PromptTokens
+
usage
.
CompletionTokens
usage
.
TotalTokens
=
usage
.
PromptTokens
+
usage
.
CompletionTokens
return
nil
,
usage
return
nil
,
usage
}
}
...
...
relay/common/relay_utils.go
View file @
1d4ebe39
package
common
package
common
import
(
import
(
"encoding/json"
"fmt"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin"
_
"image/gif"
_
"image/gif"
_
"image/jpeg"
_
"image/jpeg"
_
"image/png"
_
"image/png"
"io"
"net/http"
"one-api/common"
"one-api/common"
"one-api/dto"
"strconv"
"strings"
"strings"
)
)
var
StopFinishReason
=
"stop"
var
StopFinishReason
=
"stop"
func
RelayErrorHandler
(
resp
*
http
.
Response
)
(
OpenAIErrorWithStatusCode
*
dto
.
OpenAIErrorWithStatusCode
)
{
OpenAIErrorWithStatusCode
=
&
dto
.
OpenAIErrorWithStatusCode
{
StatusCode
:
resp
.
StatusCode
,
Error
:
dto
.
OpenAIError
{
Message
:
fmt
.
Sprintf
(
"bad response status code %d"
,
resp
.
StatusCode
),
Type
:
"upstream_error"
,
Code
:
"bad_response_status_code"
,
Param
:
strconv
.
Itoa
(
resp
.
StatusCode
),
},
}
responseBody
,
err
:=
io
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
}
err
=
resp
.
Body
.
Close
()
if
err
!=
nil
{
return
}
var
textResponse
dto
.
TextResponseWithError
err
=
json
.
Unmarshal
(
responseBody
,
&
textResponse
)
if
err
!=
nil
{
OpenAIErrorWithStatusCode
.
Error
.
Message
=
fmt
.
Sprintf
(
"error unmarshalling response body: %s"
,
responseBody
)
return
}
OpenAIErrorWithStatusCode
.
Error
=
textResponse
.
Error
return
}
func
GetFullRequestURL
(
baseURL
string
,
requestURL
string
,
channelType
int
)
string
{
func
GetFullRequestURL
(
baseURL
string
,
requestURL
string
,
channelType
int
)
string
{
fullRequestURL
:=
fmt
.
Sprintf
(
"%s%s"
,
baseURL
,
requestURL
)
fullRequestURL
:=
fmt
.
Sprintf
(
"%s%s"
,
baseURL
,
requestURL
)
...
...
relay/relay-audio.go
View file @
1d4ebe39
...
@@ -105,6 +105,7 @@ func AudioHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusCode {
...
@@ -105,6 +105,7 @@ func AudioHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusCode {
audioRequest
.
Model
=
modelMap
[
audioRequest
.
Model
]
audioRequest
.
Model
=
modelMap
[
audioRequest
.
Model
]
}
}
}
}
relayInfo
.
UpstreamModelName
=
audioRequest
.
Model
adaptor
:=
GetAdaptor
(
relayInfo
.
ApiType
)
adaptor
:=
GetAdaptor
(
relayInfo
.
ApiType
)
if
adaptor
==
nil
{
if
adaptor
==
nil
{
...
...
relay/relay-image.go
View file @
1d4ebe39
...
@@ -180,7 +180,7 @@ func RelayImageHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusC
...
@@ -180,7 +180,7 @@ func RelayImageHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusC
}
}
if
resp
.
StatusCode
!=
http
.
StatusOK
{
if
resp
.
StatusCode
!=
http
.
StatusOK
{
return
relaycommon
.
RelayErrorHandler
(
resp
)
return
service
.
RelayErrorHandler
(
resp
)
}
}
var
textResponse
dto
.
ImageResponse
var
textResponse
dto
.
ImageResponse
...
...
service/error.go
View file @
1d4ebe39
...
@@ -56,10 +56,9 @@ func RelayErrorHandler(resp *http.Response) (errWithStatusCode *dto.OpenAIErrorW
...
@@ -56,10 +56,9 @@ func RelayErrorHandler(resp *http.Response) (errWithStatusCode *dto.OpenAIErrorW
errWithStatusCode
=
&
dto
.
OpenAIErrorWithStatusCode
{
errWithStatusCode
=
&
dto
.
OpenAIErrorWithStatusCode
{
StatusCode
:
resp
.
StatusCode
,
StatusCode
:
resp
.
StatusCode
,
Error
:
dto
.
OpenAIError
{
Error
:
dto
.
OpenAIError
{
Message
:
""
,
Type
:
"upstream_error"
,
Type
:
"upstream_error"
,
Code
:
"bad_response_status_code"
,
Code
:
"bad_response_status_code"
,
Param
:
strconv
.
Itoa
(
resp
.
StatusCode
),
Param
:
strconv
.
Itoa
(
resp
.
StatusCode
),
},
},
}
}
responseBody
,
err
:=
io
.
ReadAll
(
resp
.
Body
)
responseBody
,
err
:=
io
.
ReadAll
(
resp
.
Body
)
...
...
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