1
1
package ali
2
2
3
3
import (
4
+ "encoding/json"
4
5
"errors"
5
6
"fmt"
7
+ "io"
8
+ "net/http"
9
+
6
10
"github.com/gin-gonic/gin"
11
+ "github.com/gorilla/websocket"
7
12
"github.com/songquanpeng/one-api/relay/adaptor"
8
13
"github.com/songquanpeng/one-api/relay/meta"
9
14
"github.com/songquanpeng/one-api/relay/model"
10
15
"github.com/songquanpeng/one-api/relay/relaymode"
11
- "io"
12
- "net/http"
13
16
)
14
17
15
18
// https://help.aliyun.com/zh/dashscope/developer-reference/api-details
@@ -76,7 +79,19 @@ func (a *Adaptor) ConvertImageRequest(request *model.ImageRequest) (any, error)
76
79
return aliRequest , nil
77
80
}
78
81
82
+ func (a * Adaptor ) ConvertTextToSpeechRequest (request * model.TextToSpeechRequest ) (any , error ) {
83
+ if request == nil {
84
+ return nil , errors .New ("request is nil" )
85
+ }
86
+
87
+ aliRequest := ConvertTextToSpeechRequest (* request )
88
+ return aliRequest , nil
89
+ }
90
+
79
91
func (a * Adaptor ) DoRequest (c * gin.Context , meta * meta.Meta , requestBody io.Reader ) (* http.Response , error ) {
92
+ if meta .Mode == relaymode .AudioSpeech {
93
+ return a .DoWSSRequest (c , meta , requestBody )
94
+ }
80
95
return adaptor .DoRequestHelper (a , c , meta , requestBody )
81
96
}
82
97
@@ -89,6 +104,8 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, meta *meta.Met
89
104
err , usage = EmbeddingHandler (c , resp )
90
105
case relaymode .ImagesGenerations :
91
106
err , usage = ImageHandler (c , resp )
107
+ case relaymode .AudioSpeech :
108
+ err , usage = AudioSpeechHandler (c , resp )
92
109
default :
93
110
err , usage = Handler (c , resp )
94
111
}
@@ -103,3 +120,74 @@ func (a *Adaptor) GetModelList() []string {
103
120
func (a * Adaptor ) GetChannelName () string {
104
121
return "ali"
105
122
}
123
+
124
+ func (a * Adaptor ) DoWSSRequest (c * gin.Context , meta * meta.Meta , requestBody io.Reader ) (* http.Response , error ) {
125
+ baseURL := "wss://dashscope.aliyuncs.com/api-ws/v1/inference"
126
+ var usage Usage
127
+ // Create an empty http.Response object
128
+ response := & http.Response {
129
+ StatusCode : http .StatusInternalServerError ,
130
+ Body : io .NopCloser (nil ),
131
+ }
132
+
133
+ conn , _ , err := websocket .DefaultDialer .Dial (baseURL , http.Header {"Authorization" : {"Bearer " + meta .APIKey }})
134
+ if err != nil {
135
+ return response , errors .New ("ali_wss_conn_failed" )
136
+ }
137
+ defer conn .Close ()
138
+
139
+ var requestBodyBytes []byte
140
+ requestBodyBytes , err = io .ReadAll (requestBody )
141
+ if err != nil {
142
+ return response , errors .New ("ali_failed_to_read_request_body" )
143
+ }
144
+
145
+ // Convert JSON strings to map[string]interface{}
146
+ var requestBodyMap map [string ]interface {}
147
+ err = json .Unmarshal (requestBodyBytes , & requestBodyMap )
148
+ if err != nil {
149
+ return response , errors .New ("ali_failed_to_parse_request_body" )
150
+ }
151
+
152
+ if err := conn .WriteJSON (requestBodyMap ); err != nil {
153
+ return response , errors .New ("ali_wss_write_msg_failed" )
154
+ }
155
+
156
+ const chunkSize = 1024
157
+
158
+ for {
159
+ messageType , audioData , err := conn .ReadMessage ()
160
+ if err != nil {
161
+ if err == io .EOF {
162
+ break
163
+ }
164
+ return response , errors .New ("ali_wss_read_msg_failed" )
165
+ }
166
+
167
+ var msg WSSMessage
168
+ switch messageType {
169
+ case websocket .TextMessage :
170
+ err = json .Unmarshal (audioData , & msg )
171
+ if msg .Header .Event == "task-finished" {
172
+ response .StatusCode = http .StatusOK
173
+ usage .TotalTokens = msg .Payload .Usage .Characters
174
+ return response , nil
175
+ }
176
+ case websocket .BinaryMessage :
177
+ for i := 0 ; i < len (audioData ); i += chunkSize {
178
+ end := i + chunkSize
179
+ if end > len (audioData ) {
180
+ end = len (audioData )
181
+ }
182
+ chunk := audioData [i :end ]
183
+
184
+ _ , writeErr := c .Writer .Write (chunk )
185
+ if writeErr != nil {
186
+ return response , errors .New ("wss_write_chunk_failed" )
187
+ }
188
+ }
189
+ }
190
+ }
191
+
192
+ return response , nil
193
+ }
0 commit comments