8
8
use Illuminate \Support \Str ;
9
9
use Illuminate \Http \JsonResponse ;
10
10
use Illuminate \Support \Facades \Artisan ;
11
+ use Illuminate \Support \Facades \Http ;
11
12
use Illuminate \Support \Facades \Log ;
12
13
use Illuminate \Support \Facades \Storage ;
13
14
use Illuminate \Validation \Rules \File ;
@@ -34,7 +35,8 @@ public function messages(): JsonResponse
34
35
public function chat (Request $ request ): JsonResponse
35
36
{
36
37
$ request ->validate ([
37
- 'prompt ' => 'required|string '
38
+ 'prompt ' => 'required|string ' ,
39
+ 'api_key ' => 'sometimes|string ' ,
38
40
]);
39
41
$ messages = $ request ->session ()->get ('messages ' , [$ this ->preset ]);
40
42
$ userMessage = ['role ' => 'user ' , 'content ' => $ request ->input ('prompt ' )];
@@ -51,7 +53,8 @@ public function chat(Request $request): JsonResponse
51
53
public function translate (Request $ request ): JsonResponse
52
54
{
53
55
$ request ->validate ([
54
- 'prompt ' => 'required|string '
56
+ 'prompt ' => 'required|string ' ,
57
+ 'api_key ' => 'sometimes|string ' ,
55
58
]);
56
59
$ messages = $ request ->session ()->get ('messages ' , [$ this ->preset ]);
57
60
// 判断内容是中文还是英文
@@ -85,25 +88,29 @@ public function stream(Request $request)
85
88
86
89
// 实时将流式响应数据发送到客户端
87
90
$ respData = '' ;
91
+ $ apiKey = $ request ->input ('api_key ' );
92
+ if ($ apiKey ) {
93
+ $ apiKey = base64_decode ($ apiKey );
94
+ }
88
95
header ('Access-Control-Allow-Origin: * ' );
89
96
header ('Content-type: text/event-stream ' );
90
97
header ('Cache-Control: no-cache ' );
91
98
header ('X-Accel-Buffering: no ' );
92
- OpenAI::chat ($ params , function ($ ch , $ data ) use (&$ respData ) {
99
+ OpenAI::withToken ( $ apiKey )-> chat ($ params , function ($ ch , $ data ) use ($ apiKey , &$ respData ) {
93
100
$ httpCode = curl_getinfo ($ ch , CURLINFO_HTTP_CODE );
94
101
if ($ httpCode >= 400 ) {
95
102
echo "data: [ERROR] $ httpCode " ;
96
- if ($ httpCode == 429 ) {
103
+ if (( $ httpCode == 400 || $ httpCode == 401 ) && empty ( $ apiKey ) ) {
97
104
// app key 耗尽自动切换到下一个免费的 key
98
105
Artisan::call ('app:update-open-ai-key ' );
99
106
}
100
107
} else {
101
108
$ respData .= $ data ;
102
109
echo $ data ;;
103
- ob_flush ();
104
- flush ();
105
- return strlen ($ data );
106
110
}
111
+ ob_flush ();
112
+ flush ();
113
+ return strlen ($ data );
107
114
});
108
115
109
116
// 将响应数据存储到当前会话中以便刷新页面后可以看到聊天记录
@@ -137,7 +144,8 @@ public function audio(Request $request): JsonResponse
137
144
File::types (['mp3 ' , 'mp4 ' , 'mpeg ' , 'mpga ' , 'm4a ' , 'wav ' , 'webm ' ])
138
145
->min (1 ) // 最小不低于 1 KB
139
146
->max (10 * 1024 ), // 最大不超过 10 MB
140
- ]
147
+ ],
148
+ 'api_key ' => 'sometimes|string ' ,
141
149
]);
142
150
143
151
// 保存到本地
@@ -148,24 +156,25 @@ public function audio(Request $request): JsonResponse
148
156
$ messages = $ request ->session ()->get ('messages ' , [
149
157
['role ' => 'system ' , 'content ' => 'You are GeekChat - A ChatGPT clone. Answer as concisely as possible. Make Mandarin Chinese the primary language ' ]
150
158
]);
151
-
152
159
// $path = 'audios/2023/03/09/test.wav';(测试用)
153
160
// 调用 speech to text API 将语音转化为文字
154
161
try {
155
- $ response = OpenAI::transcribe ([
162
+ $ response = OpenAI::withToken ( $ request -> input ( ' api_key ' ))-> transcribe ([
156
163
'model ' => 'whisper-1 ' ,
157
164
'file ' => curl_file_create (Storage::disk ('local ' )->path ($ path )),
158
165
'response_format ' => 'verbose_json ' ,
159
166
]);
160
167
} catch (Exception $ exception ) {
161
- return $ this -> toJsonResponse ( $ request , SYSTEM_ERROR , $ messages );
168
+ return response ()-> json ([ ' message ' => [ ' role ' => ' assistant ' , ' content ' => SYSTEM_ERROR ]] );
162
169
} finally {
163
170
Storage::disk ('local ' )->delete ($ path ); // 处理完毕删除音频文件
164
171
}
165
-
166
172
$ result = json_decode ($ response );
167
173
if (empty ($ result ->text )) {
168
- return $ this ->toJsonResponse ($ request , '对不起,我没有听清你说的话,请再试一次 ' , $ messages );
174
+ if ($ request ->input ('api_key ' )) {
175
+ return response ()->json (['message ' => ['role ' => 'assistant ' , 'content ' => '识别语音失败,请确保你的KEY有效 ' ]]);
176
+ }
177
+ return response ()->json (['message ' => ['role ' => 'assistant ' , 'content ' => '对不起,我没有听清你说的话,请再试一次 ' ]]);
169
178
}
170
179
171
180
// 接下来的流程和 ChatGPT 一样
@@ -180,20 +189,26 @@ public function audio(Request $request): JsonResponse
180
189
public function image (Request $ request ): JsonResponse
181
190
{
182
191
$ request ->validate ([
183
- 'prompt ' => 'required|string '
192
+ 'prompt ' => 'required|string ' ,
193
+ 'api_key ' => 'sometimes|string ' ,
184
194
]);
185
195
$ messages = $ request ->session ()->get ('messages ' , [$ this ->preset ]);
186
196
$ prompt = $ request ->input ('prompt ' );
187
197
$ userMsg = ['role ' => 'user ' , 'content ' => $ prompt ];
188
198
$ messages [] = $ userMsg ;
189
- $ response = OpenAI::image ([
199
+ $ apiKey = $ request ->input ('api_key ' );
200
+ $ size = '256x256 ' ;
201
+ if (!empty ($ apiKey )) {
202
+ $ size = '1024x1024 ' ;
203
+ }
204
+ $ response = OpenAI::withToken ($ apiKey )->image ([
190
205
"prompt " => $ prompt ,
191
206
"n " => 1 ,
192
- "size " => " 256x256 " ,
207
+ "size " => $ size ,
193
208
"response_format " => "url " ,
194
209
]);
195
210
$ result = json_decode ($ response );
196
- $ image = '' ;
211
+ $ image = '画图失败,如果你设置了自己的key,请确保它是有效的 ' ;
197
212
if (isset ($ result ->data [0 ]->url )) {
198
213
$ image = ' ' ;
199
214
}
@@ -212,4 +227,21 @@ public function reset(Request $request): JsonResponse
212
227
213
228
return response ()->json (['status ' => 'ok ' ]);
214
229
}
230
+
231
+ public function valid (Request $ request ): JsonResponse
232
+ {
233
+ $ request ->validate ([
234
+ 'api_key ' => 'required|string '
235
+ ]);
236
+ $ apiKey = $ request ->input ('api_key ' );
237
+ if (empty ($ apiKey )) {
238
+ return response ()->json (['valid ' => false , 'error ' => '无效的 API KEY ' ]);
239
+ }
240
+ $ response = Http::withToken ($ apiKey )->timeout (15 )
241
+ ->get (config ('openai.base_uri ' ) . '/dashboard/billing/credit_grants ' );
242
+ if ($ response ->failed ()) {
243
+ return response ()->json (['valid ' => false , 'error ' => '无效的 API KEY ' ]);
244
+ }
245
+ return response ()->json (['valid ' => true ]);
246
+ }
215
247
}
0 commit comments