Skip to content

Commit

Permalink
first commit 🐈
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean-Baptiste Loup committed Jun 26, 2023
0 parents commit 9bad46a
Show file tree
Hide file tree
Showing 10 changed files with 356 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Laravel ChatGPT

### Documentation

1. Installation:
29 changes: 29 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "ogrre/laravel-chatgpt",
"description": "Package to add chat management for openai client",
"type": "library",
"require": {
"php" : "^7.3|^8.0|^8.1",
"illuminate/database": "^7.0|^8.0|^9.0",
"illuminate/support": "10.x-dev"
},
"homepage": "https://github.com/ogrre/laravel-chatgpt",
"license": "MIT",
"authors": [
{
"name": "Ogrre",
"homepage": "https://jbloup.dev",
"role": "Developer"
}
],
"autoload": {
"psr-4": {
"Ogrre\\ChatGPT\\": "src/"
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true
}
5 changes: 5 additions & 0 deletions config/chatgpt.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [

];
49 changes: 49 additions & 0 deletions database/create_chat_gpt_tables.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('chats', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();

$table->string('model_type');
$table->unsignedBigInteger('model_id');

$table->primary(['id', 'model_type', 'model_id']);
});

Schema::create('messages', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('role');
$table->text('content');
$table->unsignedBigInteger('chat_id');
$table->foreign('chat_id')
->references('id')
->on('chats')
->onDelete('cascade');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('chats');
Schema::dropIfExists('messages');
}
};
49 changes: 49 additions & 0 deletions database/migrations/create_chat_gpt_tables.php.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('chats', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();

$table->string('model_type');
$table->unsignedBigInteger('model_id');

$table->primary(['id', 'model_type', 'model_id']);
});

Schema::create('messages', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('role');
$table->text('content');
$table->unsignedBigInteger('chat_id');
$table->foreign('chat_id')
->references('id')
->on('chats')
->onDelete('cascade');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('chats');
Schema::dropIfExists('messages');
}
};
23 changes: 23 additions & 0 deletions src/ChatRegistrar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Ogrre\ChatGPT;

use Ogrre\ChatGPT\Models\Chat;

class ChatRegistrar
{
protected string $chatClass;

public function __construct(){

$this->chatClass = config('chat.models.chat');
}

/**
* @return Chat
*/
public function getChatClass(): Chat
{
return app($this->chatClass);
}
}
63 changes: 63 additions & 0 deletions src/ChatServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Ogrre\ChatGPT;

use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;

class ChatServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register(): void
{
$this->mergeConfigFrom(
__DIR__.'/../config/chat.php', 'chat'
);
}

/**
* Bootstrap services.
*
* @return void
* @throws BindingResolutionException
*/
public function boot(): void
{
$this->app->singleton(ChatRegistrar::class, function (){
return new ChatRegistrar();
});

$this->publishes([
__DIR__.'/../config/chat.php' => config_path('chat.php'),
], 'config');

$this->publishes([
__DIR__.'/../database/migrations/create_chat_gpt_tables.php.stub' => $this->getMigrationFileName('create_chat_gpt_tables.php'),
], 'migrations');
}

/**
* @param $migrationFileName
* @return string
* @throws BindingResolutionException
*/
protected function getMigrationFileName($migrationFileName): string
{
$timestamp = date('Y_m_d_His');

$filesystem = $this->app->make(Filesystem::class);

return Collection::make($this->app->databasePath() . DIRECTORY_SEPARATOR .'migrations'.DIRECTORY_SEPARATOR)
->flatMap(function ($path) use ($filesystem, $migrationFileName) {
return $filesystem->glob($path.'*_'.$migrationFileName);
})
->push($this->app->databasePath()."/migrations/{$timestamp}_{$migrationFileName}")
->first();
}
}
70 changes: 70 additions & 0 deletions src/Models/Chat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace Ogrre\ChatGPT\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

use OpenAI;

class Chat extends Model
{
public mixed $client;

public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->client = OpenAI::client(config('openai.api_key'));
}

/**
* @var string[]
*/
protected $fillable = [
'id',
];

/**
* @var string
*/
protected $table = 'chats';

/**
* @return HasMany
*/
public function messages(): HasMany
{
return $this->hasMany(Message::class);
}

/**
* @param string $prompt
* @return $this
*/
public function send(string $prompt): static
{
$messages = $this->messages();

$user_message = new Message();
$user_message->fill([
"role" => "user",
"content" => $prompt,
]);
$messages->save($user_message);

$response = $this->client->chat()->create([
'model' => 'gpt-3.5-turbo',
'messages' => $messages,
]);

$assistant_message = new Message();
$assistant_message->fill([
"role" => "assistant",
"content" => $response->choices[0]->message->content,

]);
$messages->save($assistant_message);

return $this;
}
}
32 changes: 32 additions & 0 deletions src/Models/Message.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Ogrre\ChatGPT\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Message extends Model
{
/**
* @var string[]
*/
protected $fillable = [
'id',
'role',
'content',
'chat_id',
];

/**
* @var string
*/
protected $table = 'messages';

/**
* @return BelongsTo
*/
public function chat(): BelongsTo
{
return $this->belongsTo(Chat::class);
}
}
31 changes: 31 additions & 0 deletions src/Traits/HasChat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Ogrre\ChatGPT\Traits;

use Illuminate\Database\Eloquent\Relations\HasMany;
use Ogrre\ChatGPT\Models\Chat;

trait HasChat
{
/**
* @return HasMany
*/
public function chats(): HasMany
{
return $this->hasMany(Chat::class);
}

/**
* @param string $prompt
* @param $chat_id
* @return Chat
*/
public function chat(string $prompt, $chat_id = null): Chat
{
$chat = $chat_id ? Chat::find($chat_id) : new Chat();

$this->chats()->attach([$chat->id]);

return $chat->send($prompt);
}
}

0 comments on commit 9bad46a

Please sign in to comment.