From 0660291e88e36e3ddabc9905a7c80c9a0050fa46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Thu, 2 Mar 2023 15:37:53 +0800 Subject: [PATCH] Update V2 --- src/V2.php | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/V2.php diff --git a/src/V2.php b/src/V2.php new file mode 100644 index 0000000..9cc400e --- /dev/null +++ b/src/V2.php @@ -0,0 +1,153 @@ +key = $key; + if ($model) { + $this->model = $model; + } + if ($temperature) { + $this->temperature = $temperature; + } + if ($topP) { + $this->topP = $topP; + } + + $this->http = new Client([ + 'base_uri' => $this->baseUrl, + 'timeout' => $timeout, + 'stream' => true, + ]); + } + + /** + * 添加消息 + * @param string $message + * @param string $role + * @return void + */ + public function addMessage(string $message, string $role = 'user'): void + { + $this->messages[] = [ + 'role' => $role, + 'content' => $message, + ]; + } + + /** + * 发送消息 + * @param string $prompt + * @param string|null $user + * @param bool $stream + * @return array|StreamInterface + * @throws Exception + */ + public function ask(string $prompt, string $user = null, bool $stream = false): StreamInterface|array + { + + // 将消息添加到消息列表中 + $this->addMessage($prompt); + + $data = [ + 'model' => $this->model, + 'messages' => $this->messages, + 'stream' => $stream, + 'temperature' => $this->temperature, + 'top_p' => $this->topP, + 'n' => 1, + 'user' => $user, + ]; + + try { + $response = $this->http->post( + 'v1/chat/completions', + [ + 'json' => $data, + 'headers' => [ + 'Authorization' => $this->key, + ], + 'stream' => $stream, + ] + ); + } catch (GuzzleException $e) { + throw new Exception($e->getMessage()); + } + + // 如果是数据流模式,则直接返回数据流 + if ($stream) { + return $response->getBody(); + } + + $data = json_decode($response->getBody()->getContents(), true); + if (json_last_error() !== JSON_ERROR_NONE) { + throw new Exception('Response is not json'); + } + + if (!$this->checkFields($data)) { + throw new Exception('Field missing'); + } + + $answer = $data['choices'][0]['message']['content']; + $this->addMessage($answer, 'assistant'); + + return [ + 'answer' => $answer, + 'id' => $data['id'], + 'model' => $this->model, + 'usage' => $data['usage'], + ]; + } + + /** + * 检查响应行是否包含必要的字段 + * @param mixed $line + * @return bool + */ + public function checkFields(mixed $line): bool + { + return isset($line['choices'][0]['message']['content']) && isset($line['id']) && isset($line['usage']); + } + + /** + * 格式化流消息为数组 + * @param string $line + * @return array|false + */ + public function formatStreamMessage(string $line): array|false + { + preg_match('/data: (.*)/', $line, $matches); + if (empty($matches[1])) { + return false; + } + $line = $matches[1]; + $line = str_replace('\\"', '"', $line); + $line = str_replace("\\'", "'", $line); + $line = str_replace("\\\\", "\\", $line); + + $data = json_decode($line, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + return false; + } + + return $data; + } + +}