From 9c33f78a635781df605eccdd0042d579282bd1e4 Mon Sep 17 00:00:00 2001 From: M1Screw <14369594+M1Screw@users.noreply.github.com> Date: Fri, 9 Feb 2024 23:26:37 +0800 Subject: [PATCH 1/5] chore: update clash verge download path --- composer.lock | 12 ++++++------ config/clients.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index a70522937e..9c8f2d6155 100644 --- a/composer.lock +++ b/composer.lock @@ -123,16 +123,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.298.5", + "version": "3.298.6", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "b9bc34a8702a37a6151d843af966bf3b36aaaae3" + "reference": "0afccba68a96c0cbc10f6fc5b08c5a0e09774220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/b9bc34a8702a37a6151d843af966bf3b36aaaae3", - "reference": "b9bc34a8702a37a6151d843af966bf3b36aaaae3", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/0afccba68a96c0cbc10f6fc5b08c5a0e09774220", + "reference": "0afccba68a96c0cbc10f6fc5b08c5a0e09774220", "shasum": "" }, "require": { @@ -212,9 +212,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.298.5" + "source": "https://github.com/aws/aws-sdk-php/tree/3.298.6" }, - "time": "2024-02-07T19:05:01+00:00" + "time": "2024-02-08T19:03:23+00:00" }, { "name": "bacon/bacon-qr-code", diff --git a/config/clients.json b/config/clients.json index 1fab0265e4..6dee3f5cbc 100644 --- a/config/clients.json +++ b/config/clients.json @@ -3,7 +3,7 @@ { "name": "Clash Verge", "tagMethod": "github_release", - "gitRepo": "zzzgydi/clash-verge", + "gitRepo": "clash-verge-rev/clash-verge-rev", "savePath": "public/clients/", "downloads": [ { From 0d5d0b42706c9395e45e247c2a966ba0ea8dc475 Mon Sep 17 00:00:00 2001 From: M1Screw <14369594+M1Screw@users.noreply.github.com> Date: Fri, 9 Feb 2024 23:26:57 +0800 Subject: [PATCH 2/5] ci: only run unit test when php file is changed --- .github/workflows/unit.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 8ff67369b8..a254637fa7 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -8,7 +8,24 @@ on: workflow_dispatch: jobs: + php-file-changed: + runs-on: ubuntu-latest + outputs: + php: ${{ steps.filter.outputs.php }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + php: + - '**/*.php' + unit-test-php82: + needs: php-file-changed + if: ${{ needs.php-file-changed.outputs.php == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -20,6 +37,8 @@ jobs: php vendor/bin/phpunit unit-test-php83: + needs: php-file-changed + if: ${{ needs.php-file-changed.outputs.php == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 17b1f85da01d3e2b22ddeffa408bfdff850c3066 Mon Sep 17 00:00:00 2001 From: M1Screw <14369594+M1Screw@users.noreply.github.com> Date: Sat, 10 Feb 2024 19:55:09 +0800 Subject: [PATCH 3/5] feat: skip all old migrations for new installation --- composer.json | 30 ++++++------ composer.lock | 48 ++++++++++--------- db/2022.12_to_2022.12.1.sql | 3 +- db/migrations/2023020100-init.php | 2 +- .../2023061800-update_new_shop_data_type.php | 5 -- src/Command/Migration.php | 29 +++++++++-- 6 files changed, 67 insertions(+), 50 deletions(-) diff --git a/composer.json b/composer.json index 377c730712..a332887ec1 100644 --- a/composer.json +++ b/composer.json @@ -14,33 +14,33 @@ "ext-xml": "*", "ext-yaml": "*", "ext-zip": "*", - "anankke/omnipay-alipay": "^3.1.3", + "anankke/omnipay-alipay": "^3", "aws/aws-sdk-php": "^3", "geoip2/geoip2": "^3", - "guzzlehttp/guzzle": "^7.8.1", - "guzzlehttp/psr7": "^2.6.2", - "illuminate/database": "^10.34.2", - "illuminate/pagination": "^10.34.2", - "irazasyed/telegram-bot-sdk": "^3.13", - "lcobucci/jwt": "^5.2", - "league/omnipay": "^3.2.1", + "guzzlehttp/guzzle": "^7", + "guzzlehttp/psr7": "^2", + "illuminate/database": "^10", + "illuminate/pagination": "^10", + "irazasyed/telegram-bot-sdk": "^3", + "lcobucci/jwt": "^5", + "league/omnipay": "^3", "mailgun/mailgun-php": "^4", "nikolaposa/rate-limit": "^3", "openai-php/client": "^0", - "ozdemir/datatables": "^2.3.7", - "phpmailer/phpmailer": "^6.9.1", + "ozdemir/datatables": "^2", + "phpmailer/phpmailer": "^6", "postal/postal": "^2", - "ramsey/uuid": "^4.7.5", + "ramsey/uuid": "^4", "sendgrid/sendgrid": "^8", "sentry/sdk": "^4", - "slim/http": "^1.3", + "slim/http": "^1", "slim/slim": "^4", "smarty/smarty": "^4", "srmklive/paypal": "^3", "stripe/stripe-php": "^13", "symfony/http-client": "^7", - "symfony/translation": "^6", - "tronovav/geoip2-update": "^2.3.1", + "symfony/translation": "^6|^7", + "tronovav/geoip2-update": "^2", "twig/twig": "^3", "vectorface/googleauthenticator": "^3", "voku/anti-xss": "^4" @@ -60,7 +60,7 @@ }, "require-dev": { "nunomaduro/phpinsights": "*", - "phpunit/phpunit": "^10.5.1" + "phpunit/phpunit": "^10|^11" }, "scripts": { "update-dev-windows": [ diff --git a/composer.lock b/composer.lock index 9c8f2d6155..9f9e480277 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "dc235d13929ac6d5d47538b637435d7a", + "content-hash": "83bf52eacfb53b29ac9e01022e19a0bf", "packages": [ { "name": "anankke/omnipay-alipay", @@ -123,16 +123,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.298.6", + "version": "3.298.7", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "0afccba68a96c0cbc10f6fc5b08c5a0e09774220" + "reference": "b4d98bfc70df146774bf9b04f5ac5b39955fbad2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/0afccba68a96c0cbc10f6fc5b08c5a0e09774220", - "reference": "0afccba68a96c0cbc10f6fc5b08c5a0e09774220", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/b4d98bfc70df146774bf9b04f5ac5b39955fbad2", + "reference": "b4d98bfc70df146774bf9b04f5ac5b39955fbad2", "shasum": "" }, "require": { @@ -212,9 +212,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.298.6" + "source": "https://github.com/aws/aws-sdk-php/tree/3.298.7" }, - "time": "2024-02-08T19:03:23+00:00" + "time": "2024-02-09T19:07:04+00:00" }, { "name": "bacon/bacon-qr-code", @@ -394,26 +394,26 @@ }, { "name": "carbonphp/carbon-doctrine-types", - "version": "3.1.0", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", - "reference": "a31d3358a2a5d6ae947df1691d1f321418a5f3d5" + "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/a31d3358a2a5d6ae947df1691d1f321418a5f3d5", - "reference": "a31d3358a2a5d6ae947df1691d1f321418a5f3d5", + "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/99f76ffa36cce3b70a4a6abce41dba15ca2e84cb", + "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^7.4 || ^8.0" }, "conflict": { - "doctrine/dbal": "<4.0.0 || >=5.0.0" + "doctrine/dbal": "<3.7.0 || >=4.0.0" }, "require-dev": { - "doctrine/dbal": "^4.0.0", + "doctrine/dbal": "^3.7.0", "nesbot/carbon": "^2.71.0 || ^3.0.0", "phpunit/phpunit": "^10.3" }, @@ -443,7 +443,7 @@ ], "support": { "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", - "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.1.0" + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/2.1.0" }, "funding": [ { @@ -459,7 +459,7 @@ "type": "tidelift" } ], - "time": "2023-12-10T15:33:53+00:00" + "time": "2023-12-11T17:09:12+00:00" }, { "name": "clue/stream-filter", @@ -1400,20 +1400,20 @@ }, { "name": "illuminate/database", - "version": "v10.38.1", + "version": "v10.43.0", "source": { "type": "git", "url": "https://github.com/illuminate/database.git", - "reference": "55b4633aff7c9fbf1e14bd579835344604fe4d31" + "reference": "a98f7b989bc11994e468bb65e3ace45671e5ebce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/database/zipball/55b4633aff7c9fbf1e14bd579835344604fe4d31", - "reference": "55b4633aff7c9fbf1e14bd579835344604fe4d31", + "url": "https://api.github.com/repos/illuminate/database/zipball/a98f7b989bc11994e468bb65e3ace45671e5ebce", + "reference": "a98f7b989bc11994e468bb65e3ace45671e5ebce", "shasum": "" }, "require": { - "brick/math": "^0.9.3|^0.10.2|^0.11", + "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", "ext-pdo": "*", "illuminate/collections": "^10.0", "illuminate/container": "^10.0", @@ -1422,6 +1422,10 @@ "illuminate/support": "^10.0", "php": "^8.1" }, + "conflict": { + "carbonphp/carbon-doctrine-types": ">=3.0", + "doctrine/dbal": ">=4.0" + }, "suggest": { "doctrine/dbal": "Required to rename columns and drop SQLite columns (^3.5.1).", "ext-filter": "Required to use the Postgres database driver.", @@ -1465,7 +1469,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2023-12-20T14:23:33+00:00" + "time": "2024-01-30T15:46:52+00:00" }, { "name": "illuminate/macroable", diff --git a/db/2022.12_to_2022.12.1.sql b/db/2022.12_to_2022.12.1.sql index b400133663..bc3becada6 100644 --- a/db/2022.12_to_2022.12.1.sql +++ b/db/2022.12_to_2022.12.1.sql @@ -7,5 +7,4 @@ ALTER TABLE detect_log DROP FOREIGN KEY detect_log_ibfk_5; ALTER TABLE link DROP FOREIGN KEY link_ibfk_1; ALTER TABLE login_ip DROP FOREIGN KEY login_ip_ibfk_1; ALTER TABLE paylist DROP FOREIGN KEY paylist_ibfk_1; -ALTER TABLE user_hourly_usage DROP FOREIGN KEY user_hourly_usage_ibfk_1; -ALTER TABLE user_invite_code DROP FOREIGN KEY user_invite_code_ibfk_1; \ No newline at end of file +ALTER TABLE user_invite_code DROP FOREIGN KEY user_invite_code_ibfk_1; diff --git a/db/migrations/2023020100-init.php b/db/migrations/2023020100-init.php index de3e04776c..074a17c60d 100644 --- a/db/migrations/2023020100-init.php +++ b/db/migrations/2023020100-init.php @@ -368,7 +368,7 @@ public function up(): int public function down(): int { - echo "No reverse operation for initial migration\n"; + echo 'No reverse operation for initial migration' . PHP_EOL . PHP_EOL; return 2023020100; } diff --git a/db/migrations/2023061800-update_new_shop_data_type.php b/db/migrations/2023061800-update_new_shop_data_type.php index 9ec8eac9b1..32e344e7a5 100644 --- a/db/migrations/2023061800-update_new_shop_data_type.php +++ b/db/migrations/2023061800-update_new_shop_data_type.php @@ -153,11 +153,6 @@ public function up(): int ALTER TABLE user_coupon MODIFY COLUMN `use_count` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '累计使用次数'; ALTER TABLE user_coupon MODIFY COLUMN `create_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间'; ALTER TABLE user_coupon MODIFY COLUMN `expire_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '过期时间'; - ALTER TABLE user_hourly_usage MODIFY COLUMN `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '记录ID'; - ALTER TABLE user_hourly_usage MODIFY COLUMN `user_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '用户ID'; - ALTER TABLE user_hourly_usage MODIFY COLUMN `traffic` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '当前总流量'; - ALTER TABLE user_hourly_usage MODIFY COLUMN `hourly_usage` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '过去一小时流量'; - ALTER TABLE user_hourly_usage MODIFY COLUMN `datetime` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '记录时间'; ALTER TABLE user_invite_code MODIFY COLUMN `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '记录ID'; ALTER TABLE user_invite_code MODIFY COLUMN `code` varchar(255) NOT NULL DEFAULT '' COMMENT '邀请码'; ALTER TABLE user_invite_code MODIFY COLUMN `user_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '用户ID'; diff --git a/src/Command/Migration.php b/src/Command/Migration.php index 8cb9d7dbbe..2c689cc66e 100644 --- a/src/Command/Migration.php +++ b/src/Command/Migration.php @@ -29,13 +29,13 @@ final class Migration extends Command public function boot(): void { $reverse = false; + $current = 0; + $latest = 0; $min_version = 0; $max_version = 0; $target = $this->argv[2] ?? 0; - if ($target === 'new') { - $current = 0; - } else { + if ($target !== 'new') { $current = Config::obtain('db_version'); } @@ -49,6 +49,7 @@ public function boot(): void $max_version = PHP_INT_MAX; } else { echo 'Database is not empty, do not use "new" as version.' . PHP_EOL; + return; } } elseif (is_numeric($target)) { @@ -64,6 +65,7 @@ public function boot(): void } } else { echo 'Illegal version argument.' . PHP_EOL; + return; } @@ -81,12 +83,20 @@ public function boot(): void $version = (int) explode('-', $file, 1)[0]; echo 'Found migration version ' . $version; - if ($version <= $min_version || $version > $max_version) { + if ($version > $latest) { + $latest = $version; + } + + if ($version <= $min_version || + $version > $max_version || + ($target === 'new' && $version !== 2023020100) + ) { echo '...skip' . PHP_EOL; continue; } echo PHP_EOL; + $object = require_once BASE_PATH . '/db/migrations/' . $file; if ($object instanceof MigrationInterface) { @@ -96,15 +106,18 @@ public function boot(): void } echo PHP_EOL; + echo 'Latest database version ' . $latest . PHP_EOL . PHP_EOL; if ($reverse) { krsort($queue); + foreach ($queue as $version => $object) { echo 'Reverse on ' . $version . PHP_EOL; $current = $object->down(); } } else { ksort($queue); + foreach ($queue as $version => $object) { echo 'Forward to ' . $version . PHP_EOL; $current = $object->up(); @@ -118,7 +131,13 @@ public function boot(): void }; $stat = DB::getPdo()->prepare($sql); - $stat->execute([$current]); + + if ($target === 'new') { + $stat->execute([$latest]); + } else { + $stat->execute([$current]); + } + $count = count($queue); echo 'Migration completed. ' . $count . ' file(s) processed.' . PHP_EOL From c14ed50d4ae6d28c6fa7c00ee502cb1265e18f28 Mon Sep 17 00:00:00 2001 From: M1Screw <14369594+M1Screw@users.noreply.github.com> Date: Sat, 10 Feb 2024 21:31:58 +0800 Subject: [PATCH 4/5] feat: gemini llm backend --- config/.config.example.php | 10 ++-- src/Controllers/CallbackController.php | 11 ++-- .../Telegram/{Process.php => Telegram.php} | 4 +- src/Services/LLM.php | 60 +++++++++---------- 4 files changed, 39 insertions(+), 46 deletions(-) rename src/Services/Bot/Telegram/{Process.php => Telegram.php} (92%) diff --git a/config/.config.example.php b/config/.config.example.php index 0887aa3e98..9b6d86b43e 100644 --- a/config/.config.example.php +++ b/config/.config.example.php @@ -103,13 +103,13 @@ $_ENV['geoip_locale'] = 'en'; // Large language model powered ticket reply and more -$_ENV['llm_backend'] = 'openai'; // openai/palm/huggingface/cf-workers-ai +$_ENV['llm_backend'] = 'openai'; // openai/google-ai/huggingface/cf-workers-ai // OpenAI ChatGPT $_ENV['openai_api_key'] = ''; -$_ENV['openai_model'] = 'gpt-3.5-turbo-1106'; -// Google PaLM API -$_ENV['palm_api_key'] = ''; -$_ENV['palm_text_model'] = 'text-bison-001'; +$_ENV['openai_model'] = 'gpt-4-turbo-preview'; +// Google AI API +$_ENV['google_ai_api_key'] = ''; +$_ENV['google_ai_text_model'] = 'gemini-pro'; // Hugging Face Inference API $_ENV['huggingface_api_key'] = ''; $_ENV['huggingface_endpoint_url'] = ''; diff --git a/src/Controllers/CallbackController.php b/src/Controllers/CallbackController.php index 39761885fe..ccd5ea2138 100644 --- a/src/Controllers/CallbackController.php +++ b/src/Controllers/CallbackController.php @@ -5,7 +5,7 @@ namespace App\Controllers; use App\Models\Config; -use App\Services\Bot\Telegram\Process; +use App\Services\Bot\Telegram\Telegram; use GuzzleHttp\Exception\GuzzleException; use MaxMind\Db\Reader\InvalidDatabaseException; use Psr\Http\Message\ResponseInterface; @@ -38,12 +38,9 @@ public function telegram(ServerRequest $request, Response $response, array $args $token = $request->getQueryParam('token'); if (Config::obtain('enable_telegram') && $token === Config::obtain('telegram_request_token')) { - Process::index($request); - $result = '1'; - } else { - $result = '0'; + Telegram::process($request); + return $response->withStatus(204); } - - return $response->write($result); + return $response->withStatus(400); } } diff --git a/src/Services/Bot/Telegram/Process.php b/src/Services/Bot/Telegram/Telegram.php similarity index 92% rename from src/Services/Bot/Telegram/Process.php rename to src/Services/Bot/Telegram/Telegram.php index c8836a8119..ad2726bfea 100644 --- a/src/Services/Bot/Telegram/Process.php +++ b/src/Services/Bot/Telegram/Telegram.php @@ -11,14 +11,14 @@ use Telegram\Bot\Api; use Telegram\Bot\Exceptions\TelegramSDKException; -final class Process +final class Telegram { /** * @throws InvalidDatabaseException * @throws TelegramSDKException * @throws GuzzleException */ - public static function index(RequestInterface $request): void + public static function process(RequestInterface $request): void { $bot = new Api(Config::obtain('telegram_token')); diff --git a/src/Services/LLM.php b/src/Services/LLM.php index 44ede24bfc..a3ded5e979 100644 --- a/src/Services/LLM.php +++ b/src/Services/LLM.php @@ -22,7 +22,7 @@ public static function genTextResponse(string $q): string return match ($_ENV['llm_backend']) { 'openai' => self::textPromptGPT($q), - 'palm' => self::textPromptPaLM($q), + 'google-ai' => self::textPromptGoogleAI($q), 'huggingface' => self::textPromptHF($q), 'cf-workers-ai' => self::textPromptCF($q), default => 'No LLM backend configured', @@ -53,56 +53,52 @@ public static function textPromptGPT(string $q): string /** * @throws GuzzleException */ - public static function textPromptPaLM(string $q): string + public static function textPromptGoogleAI(string $q): string { - if ($_ENV['palm_api_key'] === '') { - return 'PaLM API key not set'; + if ($_ENV['google_ai_api_key'] === '') { + return 'Google AI API key not set'; } $client = new Client(); - $api_url = 'https://generativelanguage.googleapis.com/v1beta3/models/' . - $_ENV['palm_text_model'] . ':generateText?key=' . $_ENV['palm_api_key']; + $api_url = 'https://generativelanguage.googleapis.com/v1/models/' . + $_ENV['google_ai_text_model'] . ':generateContent?key=' . $_ENV['google_ai_api_key']; $headers = [ 'Content-Type' => 'application/json', ]; $data = [ - 'prompt' => [ - 'text' => $q, + 'contents' => [ + 'parts' => [ + [ + 'text' => $q, + ], + ], ], - 'temperature' => 1, - 'candidate_count' => 1, - 'top_k' => 40, - 'top_p' => 0.95, - 'max_output_tokens' => 1024, - 'stop_sequences' => [ + 'generationConfig' => [ + 'temperature' => 1, + 'topK' => 1, + 'topP' => 1, + 'maxOutputTokens' => 2048, + 'stopSequences' => [], ], - 'safety_settings' => [ - [ - 'category' => 'HARM_CATEGORY_DEROGATORY', - 'threshold' => 3, - ], - [ - 'category' => 'HARM_CATEGORY_TOXICITY', - 'threshold' => 3, - ], + 'safetySettings' => [ [ - 'category' => 'HARM_CATEGORY_VIOLENCE', - 'threshold' => 3, + 'category' => 'HARM_CATEGORY_HARASSMENT', + 'threshold' => 'BLOCK_NONE', ], [ - 'category' => 'HARM_CATEGORY_SEXUAL', - 'threshold' => 3, + 'category' => 'HARM_CATEGORY_HATE_SPEECH', + 'threshold' => 'BLOCK_NONE', ], [ - 'category' => 'HARM_CATEGORY_MEDICAL', - 'threshold' => 3, + 'category' => 'HARM_CATEGORY_SEXUALLY_EXPLICIT', + 'threshold' => 'BLOCK_NONE', ], [ - 'category' => 'HARM_CATEGORY_DANGEROUS', - 'threshold' => 3, + 'category' => 'HARM_CATEGORY_DANGEROUS_CONTENT', + 'threshold' => 'BLOCK_NONE', ], ], ]; @@ -113,7 +109,7 @@ public static function textPromptPaLM(string $q): string 'timeout' => 10, ])->getBody()->getContents()); - return $response->candidates[0]->output; + return $response->candidates[0]->content->parts[0]->text; } /** From a2476dde093546cf68eae810e2cac15b548bae3f Mon Sep 17 00:00:00 2001 From: M1Screw <14369594+M1Screw@users.noreply.github.com> Date: Sat, 10 Feb 2024 22:48:11 +0800 Subject: [PATCH 5/5] feat: vertex ai llm backend --- composer.lock | 14 ++++---- config/.config.example.php | 9 +++-- src/Services/LLM.php | 69 +++++++++++++++++++++++++++++++++++++- 3 files changed, 82 insertions(+), 10 deletions(-) diff --git a/composer.lock b/composer.lock index 9f9e480277..a2877764b5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "83bf52eacfb53b29ac9e01022e19a0bf", + "content-hash": "cb81eb357e69b4ed5d997458ce65a411", "packages": [ { "name": "anankke/omnipay-alipay", @@ -1977,16 +1977,16 @@ }, { "name": "mailgun/mailgun-php", - "version": "v4.0.1", + "version": "v4.1.0", "source": { "type": "git", "url": "https://github.com/mailgun/mailgun-php.git", - "reference": "c1832496b479708ca47276459268d454e557319d" + "reference": "85e598f9d0a62a978c668b689cc2169f0a4d2c59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mailgun/mailgun-php/zipball/c1832496b479708ca47276459268d454e557319d", - "reference": "c1832496b479708ca47276459268d454e557319d", + "url": "https://api.github.com/repos/mailgun/mailgun-php/zipball/85e598f9d0a62a978c668b689cc2169f0a4d2c59", + "reference": "85e598f9d0a62a978c668b689cc2169f0a4d2c59", "shasum": "" }, "require": { @@ -2032,9 +2032,9 @@ "description": "The Mailgun SDK provides methods for all API functions.", "support": { "issues": "https://github.com/mailgun/mailgun-php/issues", - "source": "https://github.com/mailgun/mailgun-php/tree/v4.0.1" + "source": "https://github.com/mailgun/mailgun-php/tree/v4.1.0" }, - "time": "2024-01-08T19:37:43+00:00" + "time": "2024-02-10T13:46:20+00:00" }, { "name": "maxmind-db/reader", diff --git a/config/.config.example.php b/config/.config.example.php index 9b6d86b43e..69f1302154 100644 --- a/config/.config.example.php +++ b/config/.config.example.php @@ -108,8 +108,13 @@ $_ENV['openai_api_key'] = ''; $_ENV['openai_model'] = 'gpt-4-turbo-preview'; // Google AI API -$_ENV['google_ai_api_key'] = ''; -$_ENV['google_ai_text_model'] = 'gemini-pro'; +$_ENV['google_ai_api_key'] = ''; +$_ENV['google_ai_model_id'] = 'gemini-pro'; +// Vertex AI API +$_ENV['vertex_ai_access_token'] = ''; +$_ENV['vertex_ai_location'] = 'us-central1'; +$_ENV['vertex_ai_model_id'] = 'gemini-pro'; +$_ENV['vertex_ai_project_id'] = ''; // Hugging Face Inference API $_ENV['huggingface_api_key'] = ''; $_ENV['huggingface_endpoint_url'] = ''; diff --git a/src/Services/LLM.php b/src/Services/LLM.php index a3ded5e979..ea990cc09f 100644 --- a/src/Services/LLM.php +++ b/src/Services/LLM.php @@ -23,6 +23,7 @@ public static function genTextResponse(string $q): string return match ($_ENV['llm_backend']) { 'openai' => self::textPromptGPT($q), 'google-ai' => self::textPromptGoogleAI($q), + 'vertex-ai' => self::textPromptVertexAI($q), 'huggingface' => self::textPromptHF($q), 'cf-workers-ai' => self::textPromptCF($q), default => 'No LLM backend configured', @@ -62,7 +63,7 @@ public static function textPromptGoogleAI(string $q): string $client = new Client(); $api_url = 'https://generativelanguage.googleapis.com/v1/models/' . - $_ENV['google_ai_text_model'] . ':generateContent?key=' . $_ENV['google_ai_api_key']; + $_ENV['google_ai_model_id'] . ':generateContent?key=' . $_ENV['google_ai_api_key']; $headers = [ 'Content-Type' => 'application/json', @@ -80,6 +81,72 @@ public static function textPromptGoogleAI(string $q): string 'temperature' => 1, 'topK' => 1, 'topP' => 1, + 'candidateCount' => 1, + 'maxOutputTokens' => 2048, + 'stopSequences' => [], + ], + 'safetySettings' => [ + [ + 'category' => 'HARM_CATEGORY_HARASSMENT', + 'threshold' => 'BLOCK_NONE', + ], + [ + 'category' => 'HARM_CATEGORY_HATE_SPEECH', + 'threshold' => 'BLOCK_NONE', + ], + [ + 'category' => 'HARM_CATEGORY_SEXUALLY_EXPLICIT', + 'threshold' => 'BLOCK_NONE', + ], + [ + 'category' => 'HARM_CATEGORY_DANGEROUS_CONTENT', + 'threshold' => 'BLOCK_NONE', + ], + ], + ]; + + $response = json_decode($client->post($api_url, [ + 'headers' => $headers, + 'json' => $data, + 'timeout' => 10, + ])->getBody()->getContents()); + + return $response->candidates[0]->content->parts[0]->text; + } + + /** + * @throws GuzzleException + */ + public static function textPromptVertexAI(string $q): string + { + if ($_ENV['vertex_ai_access_token'] === '') { + return 'Vertex AI API key not set'; + } + + $client = new Client(); + + $api_url = 'https://' . $_ENV['vertex_ai_location'] .'-aiplatform.googleapis.com/v1/projects/' . + $_ENV['vertex_ai_project_id'] . '/locations/' . $_ENV['vertex_ai_location'] . '/publishers/google/models/' . + $_ENV['vertex_ai_model_id'] . ':streamGenerateContent'; + + $headers = [ + 'Authorization' => 'Bearer ' . $_ENV['vertex_ai_access_token'], + 'Content-Type' => 'application/json', + ]; + + $data = [ + 'contents' => [ + 'parts' => [ + [ + 'text' => $q, + ], + ], + ], + 'generationConfig' => [ + 'temperature' => 1, + 'topK' => 1, + 'topP' => 1, + 'candidateCount' => 1, 'maxOutputTokens' => 2048, 'stopSequences' => [], ],