Skip to content
This repository has been archived by the owner on Nov 28, 2023. It is now read-only.

Commit

Permalink
Update V2
Browse files Browse the repository at this point in the history
  • Loading branch information
devhaozi committed Mar 2, 2023
1 parent 74b4259 commit 0660291
Showing 1 changed file with 153 additions and 0 deletions.
153 changes: 153 additions & 0 deletions src/V2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php

namespace HaoziTeam\ChatGPT;

use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\StreamInterface;
use GuzzleHttp\Client;

class V2
{
private string $baseUrl = 'https://api.openai.com/';
private string $model = 'gpt-3.5-turbo';
private string $key;
private int $temperature = 1;
private int $topP = 1;
private array $messages = [];
private mixed $http;

public function __construct(string $key, string $model = null, int $temperature = null, int $topP = null, int $timeout = 360)
{
$this->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;
}

}

0 comments on commit 0660291

Please sign in to comment.