改进和精简配置
This commit is contained in:
parent
eac2b70609
commit
6f78381f14
34
.env.example
34
.env.example
@ -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
40
Dockerfile
Normal 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" ]
|
60
app/Console/Commands/InitCommand.php
Normal file
60
app/Console/Commands/InitCommand.php
Normal 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'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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'),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -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,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'default' => env('MAIL_MAILER', 'log'),
|
'default' => env('MAIL_MAILER', 'smtp'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
@ -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
50
init.php
Normal 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');
|
||||||
|
}
|
@ -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');
|
||||||
|
Loading…
Reference in New Issue
Block a user