改进和精简配置

This commit is contained in:
Twilight 2024-07-25 15:41:50 +08:00
parent eac2b70609
commit 6f78381f14
12 changed files with 175 additions and 95 deletions

View File

@ -1,24 +1,12 @@
APP_NAME=Laravel APP_NAME=Amber
APP_ENV=local APP_ENV=local
APP_KEY= APP_KEY=
APP_DEBUG=true APP_DEBUG=true
APP_TIMEZONE=UTC APP_TIMEZONE=PRC
APP_URL=http://localhost APP_URL=http://localhost
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database
BCRYPT_ROUNDS=12 BCRYPT_ROUNDS=12
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=pgsql DB_CONNECTION=pgsql
DB_HOST=127.0.0.1 DB_HOST=127.0.0.1
DB_PORT=5432 DB_PORT=5432
@ -26,27 +14,12 @@ DB_DATABASE=amber
DB_USERNAME=root DB_USERNAME=root
DB_PASSWORD= DB_PASSWORD=
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database
CACHE_STORE=database
CACHE_PREFIX=
MEMCACHED_HOST=127.0.0.1
REDIS_CLIENT=phpredis REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1 REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null REDIS_PASSWORD=null
REDIS_PORT=6379 REDIS_PORT=6379
MAIL_MAILER=log MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1 MAIL_HOST=127.0.0.1
MAIL_PORT=2525 MAIL_PORT=2525
MAIL_USERNAME=null MAIL_USERNAME=null
@ -59,7 +32,6 @@ AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY= AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1 AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET= AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}" VITE_APP_NAME="${APP_NAME}"

40
Dockerfile Normal file
View File

@ -0,0 +1,40 @@
FROM registry.leafdev.top/leaf/docker-php-image:8.3
WORKDIR /app
COPY . /app
COPY start.sh /usr/bin/start.sh
RUN useradd -ms /bin/bash -u 1337 www && chown -R 1337:1337 /app && chmod +x /usr/bin/start.sh
# Switch to non-root user
USER www
# unset composer repo
RUN composer config -g repo.packagist composer https://packagist.org && \
rm -rf ~/.composer/cache && \
rm -rf .env && \
php init.php && rm init.php && \
composer install --no-dev && \
composer dump-autoload --optimize --no-dev --classmap-authoritative && \
composer clear-cache && \
art view:cache && \
./vendor/bin/rr get-binary && \
art octane:install --server=roadrunner
# COPY deploy/start-container /usr/local/bin/start-container
# COPY deploy/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# COPY vendor /app/vendor
# RUN chmod +x /usr/local/bin/start-container
EXPOSE 8000
# ENTRYPOINT ["start-container"]
# Start Web
# CMD [ "/usr/bin/php", "/app/artisan", "app:init", "--start" ]
CMD [ "/usr/bin/php", "/app/artisan", "octane:start", "--server=roadrunner", "--host=0.0.0.0", "--workers=1" ]
# Start queue
# CMD [ "/usr/bin/php", "/app/artisan", "init", "queue", "--tries=3", "--timeout=60" ]

View File

@ -0,0 +1,60 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class InitCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'init {type=web} {--server=roadrunner} {--host=0.0.0.0} {--port=8000} {--queue=default} {--workers=1} {--name=default}';
/**
* The console command description.
*
* @var string
*/
protected $description = '初始化应用程序(用于容器启动时)以及启动 Web 服务。 {type} 参数有 web 和 queue 两种,分别用于启动 Web 服务和队列服务。';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->call('optimize');
$type = $this->argument('type');
if ($type === 'web') {
$this->info('启动 Web 服务。');
$this->startWeb();
} else {
$this->info('启动队列服务。');
$this->startQueue();
}
return 0;
}
public function startWeb(): void
{
$this->call('octane:start', [
'--server' => $this->option('server'),
'--host' => $this->option('host'),
'--port' => $this->option('port'),
'--workers' => $this->option('workers'),
]);
}
public function startQueue(): void
{
$this->call('queue:work', [
'--queue' => $this->option('queue'),
'--name' => $this->option('name'),
]);
}
}

View File

@ -11,6 +11,7 @@ interface BaseLLM
public function setHistory(History $history); public function setHistory(History $history);
public function setTools(Collection $tools); public function setTools(Collection $tools);
public function setUser(User $user); public function setUser(User $user);
public function streamResponse(); public function streamResponse();

View File

@ -144,7 +144,7 @@ public function streamResponse()
// log // log
$event = json_decode($d, true); $event = json_decode($d, true);
// Log::debug('event', $event); // Log::debug('event', $event);
if (isset($event['choices'][0])) { if (isset($event['choices'][0])) {
$finish_reason = $event['choices'][0]['finish_reason']; $finish_reason = $event['choices'][0]['finish_reason'];
@ -155,12 +155,12 @@ public function streamResponse()
$this->history->addMessage($ai_message); $this->history->addMessage($ai_message);
yield $ai_message; yield $ai_message;
// Log::debug('stop!'); // Log::debug('stop!');
break; break;
} elseif ($finish_reason == 'tool_calls') { } elseif ($finish_reason == 'tool_calls') {
$this->retry = true; $this->retry = true;
// Log::debug('finished_reason is tool call, set retry'); // Log::debug('finished_reason is tool call, set retry');
} }
$delta = $event['choices'][0]['delta']; $delta = $event['choices'][0]['delta'];
@ -179,7 +179,7 @@ public function streamResponse()
yield $tool_req; yield $tool_req;
// Log::debug('tool req', [$tool_req]); // Log::debug('tool req', [$tool_req]);
$tool_call_message = new AIToolCallMessage(content: ''); $tool_call_message = new AIToolCallMessage(content: '');
$tool_call_message->tool_calls = [ $tool_call_message->tool_calls = [
@ -195,8 +195,8 @@ public function streamResponse()
$this->history->addMessage($tool_call_message); $this->history->addMessage($tool_call_message);
$this->history->addMessage($tool_response_message); $this->history->addMessage($tool_response_message);
// Log::debug('tool call message', [$tool_call_message]); // Log::debug('tool call message', [$tool_call_message]);
// Log::debug('tool response', [$tool_response_message]); // Log::debug('tool response', [$tool_response_message]);
yield $tool_call_message; yield $tool_call_message;
yield $tool_response_message; yield $tool_response_message;
@ -229,7 +229,7 @@ public function streamResponse()
yield $ai_chunk_message; yield $ai_chunk_message;
// Log::debug('chunk', [$ai_chunk_message]); // Log::debug('chunk', [$ai_chunk_message]);
} }
$this->retry = false; $this->retry = false;

View File

@ -11,6 +11,7 @@
class LLMTool class LLMTool
{ {
protected Tool $tool; protected Tool $tool;
protected User $user; protected User $user;
public function setTool(int $tool_id): void public function setTool(int $tool_id): void
@ -18,7 +19,7 @@ public function setTool(int $tool_id): void
$this->tool = Tool::findOrFail($tool_id); $this->tool = Tool::findOrFail($tool_id);
} }
public function setUser(User $user):void public function setUser(User $user): void
{ {
$this->user = $user; $this->user = $user;
} }
@ -46,15 +47,15 @@ public function callTool(string $function_name, $parameters = []): FunctionCall
if (empty($this->tool->api_key)) { if (empty($this->tool->api_key)) {
$r->success = false; $r->success = false;
$r->result = "[Error] 没有找到 API KEY请先在工具设置中设置 API KEY。"; $r->result = '[Error] 没有找到 API KEY请先在工具设置中设置 API KEY。';
return $r; return $r;
} }
if (!empty($this->user)) { if (! empty($this->user)) {
$data['user'] = [ $data['user'] = [
'id' => $this->user->external_id, 'id' => $this->user->external_id,
'name' => $this->user->name 'name' => $this->user->name,
]; ];
} }

View File

@ -65,7 +65,7 @@
| |
*/ */
'timezone' => env('APP_TIMEZONE', 'UTC'), 'timezone' => env('APP_TIMEZONE', 'PRC'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -119,7 +119,7 @@
*/ */
'maintenance' => [ 'maintenance' => [
'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), 'driver' => env('APP_MAINTENANCE_DRIVER', 'cache'),
'store' => env('APP_MAINTENANCE_STORE', 'database'), 'store' => env('APP_MAINTENANCE_STORE', 'database'),
], ],

View File

@ -13,7 +13,7 @@
| |
*/ */
'default' => env('FILESYSTEM_DISK', 'local'), 'default' => env('FILESYSTEM_DISK', 's3'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -29,21 +29,6 @@
*/ */
'disks' => [ 'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'throw' => false,
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
'throw' => false,
],
's3' => [ 's3' => [
'driver' => 's3', 'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'), 'key' => env('AWS_ACCESS_KEY_ID'),
@ -52,7 +37,7 @@
'bucket' => env('AWS_BUCKET'), 'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'), 'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'), 'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 'use_path_style_endpoint' => true,
'throw' => false, 'throw' => false,
], ],

View File

@ -14,7 +14,7 @@
| |
*/ */
'default' => env('MAIL_MAILER', 'log'), 'default' => env('MAIL_MAILER', 'smtp'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@ -13,7 +13,7 @@
| |
*/ */
'default' => env('QUEUE_CONNECTION', 'database'), 'default' => env('QUEUE_CONNECTION', 'redis'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -29,40 +29,10 @@
*/ */
'connections' => [ 'connections' => [
'sync' => [ 'sync' => [
'driver' => 'sync', 'driver' => 'sync',
], ],
'database' => [
'driver' => 'database',
'connection' => env('DB_QUEUE_CONNECTION'),
'table' => env('DB_QUEUE_TABLE', 'jobs'),
'queue' => env('DB_QUEUE', 'default'),
'retry_after' => (int) env('DB_QUEUE_RETRY_AFTER', 90),
'after_commit' => false,
],
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => env('BEANSTALKD_QUEUE_HOST', 'localhost'),
'queue' => env('BEANSTALKD_QUEUE', 'default'),
'retry_after' => (int) env('BEANSTALKD_QUEUE_RETRY_AFTER', 90),
'block_for' => 0,
'after_commit' => false,
],
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'default'),
'suffix' => env('SQS_SUFFIX'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'after_commit' => false,
],
'redis' => [ 'redis' => [
'driver' => 'redis', 'driver' => 'redis',
'connection' => env('REDIS_QUEUE_CONNECTION', 'default'), 'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

50
init.php Normal file
View File

@ -0,0 +1,50 @@
<?php
// 检测 storage 下的目录是否正确
$storage = '/app/storage';
// 有无 storage 目录
if (! is_dir($storage)) {
mkdir($storage);
}
// 有无 app 目录
if (! is_dir($storage.'/app')) {
mkdir($storage.'/app');
// 有无 public 目录
if (! is_dir($storage.'/app/public')) {
mkdir($storage.'/app/public');
echo "Created public directory.\n";
}
}
// 有无 framework 目录
if (! is_dir($storage.'/framework')) {
mkdir($storage.'/framework');
// 有无 cache 目录
if (! is_dir($storage.'/framework/cache')) {
mkdir($storage.'/framework/cache');
}
// 有无 sessions 目录
if (! is_dir($storage.'/framework/sessions')) {
mkdir($storage.'/framework/sessions');
}
// 有无 testing 目录
if (! is_dir($storage.'/framework/testing')) {
mkdir($storage.'/framework/testing');
}
// 有无 views 目录
if (! is_dir($storage.'/framework/views')) {
mkdir($storage.'/framework/views');
}
}
// 有无 logs 目录
if (! is_dir($storage.'/logs')) {
mkdir($storage.'/logs');
}

View File

@ -5,10 +5,11 @@
use App\Http\Controllers\Api\ChatController; use App\Http\Controllers\Api\ChatController;
use App\Http\Controllers\Api\ChatHistoryController; use App\Http\Controllers\Api\ChatHistoryController;
use App\Http\Controllers\Api\ToolController; use App\Http\Controllers\Api\ToolController;
use App\Http\Middleware\CORSMiddleware;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::middleware(['auth:api,web'])->group(function () { Route::middleware(['auth:api,web', CORSMiddleware::class])->group(function () {
Route::get('/user', function (Request $request) { Route::get('/user', function (Request $request) {
return $request->user(); return $request->user();
}); });
@ -23,4 +24,4 @@
Route::delete('assistants/{assistant}/tools/{tool}', [AssistantToolController::class, 'destroy']); Route::delete('assistants/{assistant}/tools/{tool}', [AssistantToolController::class, 'destroy']);
}); });
Route::get('chat_stream/{stream_id}', [ChatHistoryController::class, 'stream'])->name('chat-stream'); Route::middleware(CORSMiddleware::class)->get('chat_stream/{stream_id}', [ChatHistoryController::class, 'stream'])->name('chat-stream');