halilcosdu/laravel-chatbot
Composer 安装命令:
composer require halilcosdu/laravel-chatbot
包简介
A Laravel-native OpenAI chatbot powered by the Responses and Conversations APIs.
README 文档
README
A Laravel-native, stateful chatbot built on OpenAI's Responses and Conversations APIs. It manages the remote conversation, keeps a local Eloquent transcript, scopes threads to your users, and supports both synchronous and streamed responses through one facade.
Version 2.x does not use the deprecated Assistants API. If you are upgrading from 1.x, read the upgrade guide and migrate before the Assistants API shuts down on August 26, 2026.
What you get
- Responses + Conversations API integration through
openai-php/laravel. - Local
ThreadandThreadMessagemodels with configurable model classes. - Create, continue, search, paginate, inspect, and delete conversations.
- Single-use text streams for both new and existing threads.
- Automatic transcript persistence after a response completes successfully.
- Per-request Responses API options without allowing callers to replace managed input or conversation state.
- Optional owner scoping for multi-user applications.
- Raw Conversation and Response methods when you need the underlying SDK objects.
- An idempotent command for migrating 1.x Assistants threads from their local transcript.
Compatibility
| Laravel | Supported PHP versions | Testbench |
|---|---|---|
11.x (11.29+, legacy) |
8.2, 8.3, 8.4 | 9.x |
12.x (12.12+) |
8.2, 8.3, 8.4, 8.5 | 10.x |
| 13.x | 8.3, 8.4, 8.5 | 11.x |
The CI matrix tests every compatible combination above with both lowest and stable dependency sets. Laravel 11 reached upstream security end-of-life on March 12, 2026. Version 2.1 retains Laravel 11 runtime compatibility for migrations, but production applications should upgrade to Laravel 12 or 13. The Laravel 11 CI jobs use Composer's --no-blocking option solely to resolve that end-of-life framework; the package does not weaken a consuming application's Composer security policy.
Laravel 11 is not listed with PHP 8.5 because Laravel's support policy ends its PHP range at 8.4; use Laravel 12 or 13 when deploying on PHP 8.5.
Additional requirements:
openai-php/laravel^0.20- An OpenAI API key
- A database supported by your Laravel version
Installation
Install the package with Composer:
composer require halilcosdu/laravel-chatbot
Publish its configuration and migrations, then migrate:
php artisan vendor:publish --tag=chatbot-config php artisan vendor:publish --tag=chatbot-migrations php artisan migrate
Laravel discovers the service provider and ChatBot facade automatically.
Environment
At minimum, configure your API key:
OPENAI_API_KEY=sk-... OPENAI_MODEL=gpt-5.4-mini OPENAI_TIMEOUT=30
Optional values:
OPENAI_INSTRUCTIONS="You are a concise support assistant." OPENAI_ORGANIZATION= OPENAI_PROJECT=
OPENAI_PROMPT_ID remains available for applications already using reusable prompt objects. OpenAI's deprecation schedule says reusable prompts will shut down on November 30, 2026, so new integrations should keep instructions in application configuration instead.
Configuration
The published config/chatbot.php contains:
use HalilCosdu\ChatBot\Models\Thread; use HalilCosdu\ChatBot\Models\ThreadMessage; return [ 'model' => env('OPENAI_MODEL', 'gpt-5.4-mini'), 'instructions' => env('OPENAI_INSTRUCTIONS'), 'prompt_id' => env('OPENAI_PROMPT_ID'), 'api_key' => env('OPENAI_API_KEY'), 'organization' => env('OPENAI_ORGANIZATION'), 'project' => env('OPENAI_PROJECT'), 'request_timeout' => (int) env('OPENAI_TIMEOUT', 30), 'response_options' => [], 'models' => [ 'thread' => env('CHATBOT_THREAD_MODEL', Thread::class), 'thread_messages' => env('CHATBOT_THREAD_MESSAGE_MODEL', ThreadMessage::class), ], ];
Put options shared by every managed response in response_options:
'response_options' => [ 'max_output_tokens' => 1200, 'reasoning' => ['effort' => 'low'], ],
The package always supplies input and conversation, and it chooses streaming internally. Those keys cannot be replaced through managed thread methods.
The chatbot client is container-isolated from openai-php/laravel's application-level ClientContract. Your application's own OpenAI binding and config/openai.php can therefore coexist without replacing the credentials or timeout used by this package.
Quick start
use HalilCosdu\ChatBot\Facades\ChatBot; $thread = ChatBot::createThread( 'Explain why the sky is blue.', ownerId: auth()->id(), ); $assistantMessage = ChatBot::updateThread( 'Why does it turn red at sunset?', id: $thread->getKey(), ownerId: auth()->id(), ); echo $assistantMessage->content;
The package creates one remote Conversation and stores the user and assistant messages locally. Later calls reuse the remote conversation ID so OpenAI retains the conversation state.
Managed API
| Method | Result | Purpose |
|---|---|---|
createThread($subject, $ownerId, $options) |
Eloquent thread | Create a conversation and wait for the first answer. |
createThreadStreamed($subject, $ownerId, $options) |
StreamedThreadResponse |
Create a conversation and iterate its first answer as text deltas. |
updateThread($message, $id, $ownerId, $options) |
Eloquent message | Continue a conversation and wait for the answer. |
updateThreadStreamed($message, $id, $ownerId, $options) |
StreamedThreadResponse |
Continue a conversation and iterate text deltas. |
listThreads($ownerId, $search, $appends) |
paginator | List newest threads, optionally scoped and searched. |
thread($id, $ownerId) |
Eloquent thread | Retrieve a thread with its messages. |
deleteThread($id, $ownerId) |
void |
Delete the remote Conversation and local thread. |
Per-request options
The final $options argument is merged over response_options. It is useful for changing a model, token budget, reasoning effort, metadata, or supported tools for one request:
$message = ChatBot::updateThread( message: 'Give me the short version.', id: $thread->getKey(), ownerId: auth()->id(), options: [ 'model' => 'gpt-5.4-mini', 'max_output_tokens' => 300, 'reasoning' => ['effort' => 'low'], 'metadata' => ['feature' => 'support-chat'], ], );
Passing a model explicitly bypasses a configured prompt_id. Passing a prompt uses that prompt and omits model and instructions, matching the package's existing prompt behavior.
Streaming responses
Streaming uses the Responses API's semantic events internally and exposes only text deltas. The returned object also gives you the local thread immediately:
$stream = ChatBot::createThreadStreamed( 'Write a short welcome message.', ownerId: auth()->id(), ); $threadId = $stream->thread->getKey(); foreach ($stream as $delta) { echo $delta; } // Available only after the stream has completed. $savedMessage = $stream->assistantMessage(); $completed = $stream->completed();
StreamedThreadResponse is intentionally single-use. A successful terminal response.completed event is required before the package stores the assistant message. If the stream fails, ends early, or the consumer disconnects, the user message remains in the local transcript but no incomplete assistant message is invented.
Laravel streamed HTTP response
use HalilCosdu\ChatBot\Facades\ChatBot; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::post('/chat', function (Request $request) { $stream = ChatBot::createThreadStreamed( subject: $request->string('message')->toString(), ownerId: $request->user()->getAuthIdentifier(), ); return response()->stream(function () use ($stream): void { foreach ($stream as $delta) { echo $delta; if (ob_get_level() > 0) { ob_flush(); } flush(); } }, 200, [ 'Cache-Control' => 'no-cache, no-transform', 'Content-Type' => 'text/plain; charset=utf-8', 'X-Accel-Buffering' => 'no', 'X-Chatbot-Thread' => (string) $stream->thread->getKey(), ]); });
Reverse proxies may buffer output even when PHP flushes it. Disable buffering for this endpoint in your web server or proxy configuration. Streaming partial output also makes moderation harder than moderating a completed answer; account for that in production applications.
Listing and owner isolation
$threads = ChatBot::listThreads( ownerId: auth()->id(), search: 'invoice', appends: request()->query(), ); $thread = ChatBot::thread($id, ownerId: auth()->id()); ChatBot::deleteThread($id, ownerId: auth()->id());
Pass the authenticated owner's ID to every read, update, stream, and delete call. The package applies the owner condition in the database query, including valid IDs such as 0; a mismatched owner receives Laravel's normal ModelNotFoundException.
Local data and custom models
threads stores the owner, short subject, and remote Conversation ID. thread_messages stores the ordered local transcript and is deleted with its parent thread.
To add casts, relationships, or tenant behavior, extend the package models:
namespace App\Models; use HalilCosdu\ChatBot\Models\Thread as BaseThread; class ChatThread extends BaseThread { protected $table = 'threads'; }
Then configure the class:
CHATBOT_THREAD_MODEL="App\Models\ChatThread" CHATBOT_THREAD_MESSAGE_MODEL="App\Models\ChatThreadMessage"
Custom classes must be Eloquent models. Extending the package models is recommended so their relationship methods and bundled factories remain available. The package always uses the stable thread_id foreign key, even when your custom class has a different name.
Raw OpenAI access
Raw methods return the SDK's typed response objects and do not write local models:
ChatBot::createConversationAsRaw(['metadata' => ['tenant' => 'acme']]); ChatBot::conversationAsRaw($conversationId); ChatBot::updateConversationAsRaw($conversationId, ['metadata' => ['state' => 'active']]); ChatBot::listConversationItemsAsRaw($conversationId, ['limit' => 20]); ChatBot::deleteConversationAsRaw($conversationId); ChatBot::createResponseAsRaw([ 'model' => 'gpt-5.4-mini', 'input' => 'Hello', ]); $events = ChatBot::createResponseStreamedAsRaw([ 'model' => 'gpt-5.4-mini', 'input' => 'Hello', ]); foreach ($events as $event) { // Inspect $event->event and the typed $event->response payload. } ChatBot::responseAsRaw($responseId);
Use the managed methods when you want conversation continuity and local persistence. Use the raw methods when you need API features that the managed text workflow does not interpret.
Migrating from 1.x
Version 1.x used Assistants threads (thread_*); version 2.x uses Conversations (conv_*). These IDs are not interchangeable.
After publishing and running the 2.x migrations, inspect and migrate your local transcripts:
php artisan chatbot:migrate-to-conversations --dry-run php artisan chatbot:migrate-to-conversations
Useful options:
php artisan chatbot:migrate-to-conversations --limit=100
The command:
- selects only threads without
remote_conversation_id; - reconstructs user messages as
input_textand assistant messages asoutput_text; - skips empty transcripts;
- continues after individual API failures and returns a failing exit code if any fail;
- is idempotent, so it can be run again safely.
See UPGRADE.md for the complete 1.x to 2.x migration guide.
Error handling
Managed responses throw HalilCosdu\ChatBot\Exceptions\ChatBotException when OpenAI returns a failed or incomplete response, produces no text, or ends a stream without a completion event.
use HalilCosdu\ChatBot\Exceptions\ChatBotException; try { $message = ChatBot::updateThread('Hello', $threadId, auth()->id()); } catch (ChatBotException $exception) { report($exception); return back()->withErrors(['chat' => 'The assistant could not complete its response.']); }
Transport and authentication errors from the underlying SDK are not hidden. Laravel's ModelNotFoundException is also preserved for missing or incorrectly scoped threads.
Testing and quality
Run the complete local quality gate:
composer test-all
Or run checks independently:
composer test
composer analyse
composer format-test
composer test-coverage
The GitHub compatibility workflow covers PHP 8.2 through 8.5 across Laravel 11, 12, and 13 using each framework's supported PHP range.
Security
Please do not publish API keys, prompts containing secrets, or sensitive transcript data in issues. Report vulnerabilities privately using the process in SECURITY.md.
Changelog
See CHANGELOG.md for release history.
Credits
License
Laravel Chatbot is open-sourced software licensed under the MIT license.
halilcosdu/laravel-chatbot 适用场景与选型建议
halilcosdu/laravel-chatbot 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 5.75k 次下载、GitHub Stars 达 65, 最近一次更新时间为 2024 年 04 月 17 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「laravel」 「ai」 「chatbot」 「openai」 「laravel-chatbot」 「responses-api」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 halilcosdu/laravel-chatbot 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 halilcosdu/laravel-chatbot 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 halilcosdu/laravel-chatbot 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
PHP 8.0+ OpenAI API client with fully typed/documented requests+responses models, guzzle and symfony/http-client support and async/parallel requests.
Estimate AI API costs before making expensive calls
A powerful package that seamlessly integrates OpenAI's advanced AI capabilities into your Laravel applications. This package offers quick setup and intuitive configuration to leverage AI models for chat, embeddings, and more.
AI discussion summaries for Flarum with real-time streaming.
Alfabank REST API integration
A simple laravel wrapper for linecorp/line-bot-sdk
统计信息
- 总下载量: 5.75k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 65
- 点击次数: 25
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2024-04-17