From 516b997a1c417c3cfcf6bc865943ff28da0fd65f Mon Sep 17 00:00:00 2001 From: Mathieu Date: Fri, 1 Dec 2023 11:45:14 +0100 Subject: [PATCH] Rename Gpt to Embed (#5) --- .github/ISSUE_TEMPLATE/config.yml | 6 +- CHANGELOG.md | 2 +- composer.json | 10 +- config/embed.php | 15 ++ config/gpt.php | 15 -- database/factories/ModelFactory.php | 2 +- ...e_gpt_table.php => create_embed_table.php} | 8 +- database/migrations/create_gpt_table.php.stub | 19 --- package-lock.json | 2 +- ...GptCommand.php => LaravelEmbedCommand.php} | 6 +- src/Embed.php | 43 ++++++ src/{Gptable.php => Embeddable.php} | 144 +++++++++--------- ...vider.php => EmbeddingServiceProvider.php} | 12 +- src/EngineManager.php | 18 +-- src/Engines/EngineInterface.php | 2 +- src/Engines/OpenAiEngine.php | 16 +- src/Facades/LaravelEmbed.php | 16 ++ src/Facades/LaravelGpt.php | 16 -- src/Gpt.php | 43 ------ .../{MakeGptable.php => MakeEmbeddable.php} | 8 +- ...{RemoveFromGpt.php => RemoveFromEmbed.php} | 18 +-- src/Jobs/RemoveableEmbedCollection.php | 24 +++ src/Jobs/RemoveableGptCollection.php | 24 --- src/ModelObserver.php | 18 +-- tests/Pest.php | 2 +- tests/TestCase.php | 10 +- 26 files changed, 240 insertions(+), 259 deletions(-) create mode 100644 config/embed.php delete mode 100644 config/gpt.php rename database/migrations/{create_gpt_table.php => create_embed_table.php} (73%) delete mode 100644 database/migrations/create_gpt_table.php.stub rename src/Commands/{LaravelGptCommand.php => LaravelEmbedCommand.php} (61%) create mode 100644 src/Embed.php rename src/{Gptable.php => Embeddable.php} (50%) rename src/{LaravelGptServiceProvider.php => EmbeddingServiceProvider.php} (61%) create mode 100644 src/Facades/LaravelEmbed.php delete mode 100644 src/Facades/LaravelGpt.php delete mode 100644 src/Gpt.php rename src/Jobs/{MakeGptable.php => MakeEmbeddable.php} (73%) rename src/Jobs/{RemoveFromGpt.php => RemoveFromEmbed.php} (70%) create mode 100644 src/Jobs/RemoveableEmbedCollection.php delete mode 100644 src/Jobs/RemoveableGptCollection.php diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index e648c7a..320d74e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,11 @@ blank_issues_enabled: false contact_links: - name: Ask a question - url: https://github.com/vormkracht10/laravel-gpt/discussions/new?category=q-a + url: https://github.com/vormkracht10/laravel-embeddings/discussions/new?category=q-a about: Ask the community for help - name: Request a feature - url: https://github.com/vormkracht10/laravel-gpt/discussions/new?category=ideas + url: https://github.com/vormkracht10/laravel-embeddings/discussions/new?category=ideas about: Share ideas for new features - name: Report a security issue - url: https://github.com/vormkracht10/laravel-gpt/security/policy + url: https://github.com/vormkracht10/laravel-embeddings/security/policy about: Learn how to notify us for sensitive bugs diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f2a4f8..2bf205c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ # Changelog -All notable changes to `laravel-gpt` will be documented in this file. +All notable changes to `laravel-embeddings` will be documented in this file. diff --git a/composer.json b/composer.json index 00d6b90..0fb2acc 100644 --- a/composer.json +++ b/composer.json @@ -32,13 +32,13 @@ }, "autoload": { "psr-4": { - "Vormkracht10\\LaravelGpt\\": "src/", - "Vormkracht10\\LaravelGpt\\Database\\Factories\\": "database/factories/" + "Vormkracht10\\Embedding\\": "src/", + "Vormkracht10\\Embedding\\Database\\Factories\\": "database/factories/" } }, "autoload-dev": { "psr-4": { - "Vormkracht10\\LaravelGpt\\Tests\\": "tests/" + "Vormkracht10\\Embedding\\Tests\\": "tests/" } }, "scripts": { @@ -58,10 +58,10 @@ "extra": { "laravel": { "providers": [ - "Vormkracht10\\LaravelGpt\\LaravelGptServiceProvider" + "Vormkracht10\\Embedding\\EmbeddingServiceProvider" ], "aliases": { - "LaravelGpt": "Vormkracht10\\LaravelGpt\\Facades\\LaravelGpt" + "Embedding": "Vormkracht10\\Embedding\\Facades\\Embedding" } } }, diff --git a/config/embed.php b/config/embed.php new file mode 100644 index 0000000..e68216c --- /dev/null +++ b/config/embed.php @@ -0,0 +1,15 @@ + env('EMBED_ENABLED', true), + 'driver' => env('EMBED_DRIVER', 'openai'), + 'queue' => true, + 'database' => [ + 'connection' => env('EMBED_DATABASE_CONNECTION', 'pgsql'), + 'table' => env('EMBED_DB_TABLE', 'embeddings'), + ], + 'openai' => [ + 'key' => env('OPENAI_API_KEY'), + ], +]; diff --git a/config/gpt.php b/config/gpt.php deleted file mode 100644 index 228a556..0000000 --- a/config/gpt.php +++ /dev/null @@ -1,15 +0,0 @@ - env('GPT_ENABLED', true), - 'driver' => env('GPT_DRIVER', 'openai'), - 'queue' => true, - 'database' => [ - 'connection' => env('GPT_DATABASE_CONNECTION', env('DB_CONNECTION', 'mysql')), - 'table' => env('GPT_DB_TABLE', 'gpt'), - ], - 'openai' => [ - 'key' => env('OPENAI_API_KEY'), - ], -]; diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index 9610b57..ad6fa07 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -1,6 +1,6 @@ connection = config('gpt.database.connection'); + $this->connection = config('embed.database.connection'); } public function up() { - if (Schema::connection($this->connection)->hasTable(config('gpt.database.table'))) { + if (Schema::connection($this->connection)->hasTable(config('embed.database.table'))) { return; } - Schema::create(config('gpt.database.table'), function (Blueprint $table) { + Schema::create(config('embed.database.table'), function (Blueprint $table) { $table->bigIncrements('id'); $table->bigInteger('foreign_id'); $table->text('content'); $table->timestamps(); }); - $tableName = config('gpt.database.table'); + $tableName = config('embed.database.table'); DB::statement("ALTER TABLE {$tableName} ADD COLUMN embedding vector(1536) NULL;"); } diff --git a/database/migrations/create_gpt_table.php.stub b/database/migrations/create_gpt_table.php.stub deleted file mode 100644 index 2042649..0000000 --- a/database/migrations/create_gpt_table.php.stub +++ /dev/null @@ -1,19 +0,0 @@ -id(); - - // add fields - - $table->timestamps(); - }); - } -}; diff --git a/package-lock.json b/package-lock.json index 9ba8ce0..7a3229b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "laravel-gpt", + "name": "laravel-embeddings", "lockfileVersion": 3, "requires": true, "packages": {} diff --git a/src/Commands/LaravelGptCommand.php b/src/Commands/LaravelEmbedCommand.php similarity index 61% rename from src/Commands/LaravelGptCommand.php rename to src/Commands/LaravelEmbedCommand.php index 0262c0f..8955001 100644 --- a/src/Commands/LaravelGptCommand.php +++ b/src/Commands/LaravelEmbedCommand.php @@ -1,12 +1,12 @@ registerGptableMacros(); + (new static)->registerEmbeddableMacros(); } /** - * Register the gptable macros. + * Register the embeddable macros. * * @return void */ - public function registerGptableMacros() + public function registerEmbeddableMacros() { $self = $this; - BaseCollection::macro('gptable', function () use ($self) { - $self->queueMakeGptable($this); + BaseCollection::macro('embeddable', function () use ($self) { + $self->queueMakeEmbeddable($this); }); - BaseCollection::macro('ungptable', function () use ($self) { - $self->queueRemoveFromGpt($this); + BaseCollection::macro('unembeddable', function () use ($self) { + $self->queueRemoveFromEmbed($this); }); } /** - * Dispatch the job to make the given models gptable. + * Dispatch the job to make the given models embeddable. * * @param \Illuminate\Database\Eloquent\Collection $models * @return void */ - public function queueMakeGptable($models) + public function queueMakeEmbeddable($models) { if ($models->isEmpty()) { return; } - if (! config('gpt.queue')) { - return $models->first()->makeGptableUsing($models)->first()->makeGptableUsing()->update($models); + if (! config('embed.queue')) { + return $models->first()->makeEmbeddableUsing($models)->first()->makeEmbeddableUsing()->update($models); } - dispatch((new Gpt::$makeGptableJob($models)) - ->onQueue($models->first()->syncWithGptUsingQueue()) - ->onConnection($models->first()->syncWithGptUsing())); + dispatch((new Embed::$makeEmbeddableJob($models)) + ->onQueue($models->first()->syncWithEmbedUsingQueue()) + ->onConnection($models->first()->syncWithEmbedUsing())); } /** - * Dispatch the job to make the given models ungptable. + * Dispatch the job to make the given models unembeddable. * * @param \Illuminate\Database\Eloquent\Collection $models * @return void */ - public function queueRemoveFromGpt($models) + public function queueRemoveFromEmbed($models) { if ($models->isEmpty()) { return; } - if (! config('gpt.queue')) { - return $models->first()->gptableUsing()->delete($models); + if (! config('embed.queue')) { + return $models->first()->embeddableUsing()->delete($models); } - dispatch(new Gpt::$removeFromGptJob($models)) - ->onQueue($models->first()->syncWithGptUsingQueue()) - ->onConnection($models->first()->syncWithGptUsing()); + dispatch(new Embed::$removeFromEmbedJob($models)) + ->onQueue($models->first()->syncWitEmbedUsingQueue()) + ->onConnection($models->first()->syncWitEmbedUsing()); } /** - * Determine if the model should be gptable. + * Determine if the model should be embeddable. * * @return bool */ - public function shouldBeGptable() + public function shouldBeEmbeddable() { return true; } /** - * When updating a model, this method determines if we should update the gpt index. + * When updating a model, this method determines if we should update the embed index. * * @return bool */ - public function gptIndexShouldBeUpdated() + public function embedIndexShouldBeUpdated() { return true; } /** - * Make all instances of the model gptable. + * Make all instances of the model embeddable. * * @param int $chunk * @return void */ - public static function makeAllGptable($chunk = null) + public static function makeAllEmbeddable($chunk = null) { $self = new static; - $softDelete = static::usesSoftDelete() && config('gpt.soft_delete', false); + $softDelete = static::usesSoftDelete() && config('embed.soft_delete', false); $self->newQuery() ->when(true, function ($query) use ($self) { - $self->makeAllGptableUsing($query); + $self->makeAllEmbeddableUsing($query); }) ->when($softDelete, function ($query) { $query->withTrashed(); }) ->orderBy( - $self->qualifyColumn($self->getGptKeyName()) + $self->qualifyColumn($self->getEmbedKeyName()) ) - ->gptable($chunk); + ->embeddable($chunk); } /** - * Modify the collection of models being made gptable. + * Modify the collection of models being made embeddable. * * @return \Illuminate\Support\Collection */ - public function makeGptableUsing(BaseCollection $models) + public function makeEmbeddableUsing(BaseCollection $models) { return $models; } /** - * Modify the query used to retrieve models when making all of the models gptable. + * Modify the query used to retrieve models when making all of the models embeddable. * * @return \Illuminate\Database\Eloquent\Builder */ - protected function makeAllGptableUsing(EloquentBuilder $query) + protected function makeAllEmbeddableUsing(EloquentBuilder $query) { return $query; } /** - * Make the given model instance gptable. + * Make the given model instance embeddable. * * @return void */ - public function gptable() + public function embeddable() { - $this->newCollection([$this])->gptable(); + $this->newCollection([$this])->embeddable(); } /** - * Remove all instances of the model from the gpt index. + * Remove all instances of the model from the embed index. * * @return void */ - public static function removeAllFromGpt() + public static function removeAllFromEmbed() { $self = new static; - $self->gptableUsing()->flush($self); + $self->embeddableUsing()->flush($self); } /** - * Remove the given model instance from the gpt index. + * Remove the given model instance from the embed index. * * @return void */ - public function ungptable() + public function unembeddable() { - $this->newCollection([$this])->ungptable(); + $this->newCollection([$this])->unembeddable(); } /** - * Determine if the model existed in the gpt index prior to an update. + * Determine if the model existed in the embed index prior to an update. * * @return bool */ - public function wasGptableBeforeUpdate() + public function wasEmbeddableBeforeUpdate() { return true; } /** - * Determine if the model existed in the gpt index prior to deletion. + * Determine if the model existed in the embed index prior to deletion. * * @return bool */ - public function wasGptableBeforeDelete() + public function wasEmbeddableBeforeDelete() { return true; } /** - * Enable gpt syncing for this model. + * Enable embed syncing for this model. * * @return void */ - public static function enableGptSyncing() + public static function enableEmbedSyncing() { ModelObserver::enableSyncingFor(get_called_class()); } /** - * Disable gpt syncing for this model. + * Disable embed syncing for this model. * * @return void */ - public static function disableGptSyncing() + public static function disableEmbedSyncing() { ModelObserver::disableSyncingFor(get_called_class()); } /** - * Temporarily disable gpt syncing for the given callback. + * Temporarily disable embed syncing for the given callback. * * @param callable $callback * @return mixed */ - public static function withoutSyncingToGpt($callback) + public static function withoutSyncingToEmbed($callback) { - static::disableGptSyncing(); + static::disableEmbedSyncing(); try { return $callback(); } finally { - static::enableGptSyncing(); + static::enableEmbedSyncing(); } } @@ -239,9 +239,9 @@ public static function withoutSyncingToGpt($callback) * * @return string */ - public function gptableAs() + public function embeddableAs() { - return config('gpt.prefix').$this->getTable(); + return config('embed.prefix').$this->getTable(); } /** @@ -249,17 +249,17 @@ public function gptableAs() * * @return array */ - public function toGptableString() + public function toEmbeddableString() { return strip_tags(implode(', ', $this->contentable->toArray()).implode(', ', $this->toArray())); } /** - * Get the Gpt engine for the model. + * Get the Embed engine for the model. * * @return mixed */ - public function gptableUsing() + public function embeddableUsing() { return app(EngineManager::class)->engine(); } @@ -269,9 +269,9 @@ public function gptableUsing() * * @return string */ - public function syncWithGptUsing() + public function syncWithEmbedUsing() { - return config('gpt.queue.connection') ?: config('queue.default'); + return config('embed.queue.connection') ?: config('queue.default'); } /** @@ -279,9 +279,9 @@ public function syncWithGptUsing() * * @return string */ - public function syncWithGptUsingQueue() + public function syncWithEmbedUsingQueue() { - return config('gpt.queue.queue'); + return config('embed.queue.queue'); } /** @@ -289,7 +289,7 @@ public function syncWithGptUsingQueue() * * @return mixed */ - public function getGptKey() + public function getEmbedKey() { return $this->getKey(); } @@ -299,7 +299,7 @@ public function getGptKey() * * @return string */ - public function getGptKeyType() + public function getEmbedKeyType() { return $this->getKeyType(); } @@ -309,13 +309,13 @@ public function getGptKeyType() * * @return mixed */ - public function getGptKeyName() + public function getEmbedKeyName() { return $this->getKeyName(); } /** - * Determine if the current class should use soft deletes with gpting. + * Determine if the current class should use soft deletes with embedding. * * @return bool */ diff --git a/src/LaravelGptServiceProvider.php b/src/EmbeddingServiceProvider.php similarity index 61% rename from src/LaravelGptServiceProvider.php rename to src/EmbeddingServiceProvider.php index 7b177c1..5c01982 100644 --- a/src/LaravelGptServiceProvider.php +++ b/src/EmbeddingServiceProvider.php @@ -1,10 +1,10 @@ mergeConfigFrom(__DIR__.'/../config/gpt.php', 'gpt'); + $this->mergeConfigFrom(__DIR__.'/../config/embed.php', 'embed'); } /** @@ -25,11 +25,11 @@ public function boot() { if ($this->app->runningInConsole()) { $this->publishes([ - __DIR__.'/../config/gpt.php' => config_path('gpt.php'), - ], 'laravel-gpt-config'); + __DIR__.'/../config/embed.php' => config_path('embed.php'), + ], 'laravel-embed-config'); $this->publishes([ __DIR__.'/../database/migrations/' => database_path('migrations'), - ], 'laravel-gpt-migrations'); + ], 'laravel-embed-migrations'); } } } diff --git a/src/EngineManager.php b/src/EngineManager.php index f965b86..b77534c 100644 --- a/src/EngineManager.php +++ b/src/EngineManager.php @@ -1,9 +1,9 @@ ensureOpenAiIsConfigured(); - return new OpenAiEngine(config('gpt.openai.key')); + return new OpenAiEngine(config('embed.openai.key')); } /** @@ -39,8 +39,8 @@ public function createOpenAiDriver() */ protected function ensureOpenAiIsConfigured() { - if (empty(config('gpt.openai.key'))) { - throw new \Exception(__('Please fill the :config key.', ['config' => 'gpt.openai.key'])); + if (empty(config('embed.openai.key'))) { + throw new \Exception(__('Please fill the :config key.', ['config' => 'embed.openai.key'])); } } @@ -57,13 +57,13 @@ public function forgetEngines() } /** - * Get the default Gpt driver name. + * Get the default Embed driver name. * * @return string */ public function getDefaultDriver() { - if (is_null($driver = config('gpt.driver'))) { + if (is_null($driver = config('embed.driver'))) { return 'openai'; } diff --git a/src/Engines/EngineInterface.php b/src/Engines/EngineInterface.php index 044f072..a1202f7 100644 --- a/src/Engines/EngineInterface.php +++ b/src/Engines/EngineInterface.php @@ -1,6 +1,6 @@ map(function ($model) { - if (empty($contentString = $model->toGptableString())) { + if (empty($contentString = $model->toEmbeddableString())) { return; } return [ - 'objectID' => $model->getGptKey(), + 'objectID' => $model->getEmbedKey(), 'content' => $contentString, ]; })->filter()->values()->all(); @@ -62,8 +62,8 @@ private function saveObjects($objects) $embed = $this->embed($object['content']); - DB::connection(config('gpt.database.connection')) - ->table(config('gpt.database.table')) + DB::connection(config('embed.database.connection')) + ->table(config('embed.database.table')) ->updateOrInsert([ 'foreign_id' => $object['objectID'], ], [ @@ -82,9 +82,9 @@ private function saveObjects($objects) public function delete($models) { foreach ($models as $model) { - DB::connection(config('gpt.database.connection')) - ->table(config('gpt.database.table')) - ->where('foreign_id', $model->getGptKey()) + DB::connection(config('embed.database.connection')) + ->table(config('embed.database.table')) + ->where('foreign_id', $model->getEmbedKey()) ->delete(); } } diff --git a/src/Facades/LaravelEmbed.php b/src/Facades/LaravelEmbed.php new file mode 100644 index 0000000..44e3409 --- /dev/null +++ b/src/Facades/LaravelEmbed.php @@ -0,0 +1,16 @@ +models->first()->makeGptableUsing($this->models)->first()->gptableUsing()->update($this->models); + $this->models->first()->makeEmbeddableUsing($this->models)->first()->embeddableUsing()->update($this->models); } } diff --git a/src/Jobs/RemoveFromGpt.php b/src/Jobs/RemoveFromEmbed.php similarity index 70% rename from src/Jobs/RemoveFromGpt.php rename to src/Jobs/RemoveFromEmbed.php index e58d8a1..0c38b8f 100644 --- a/src/Jobs/RemoveFromGpt.php +++ b/src/Jobs/RemoveFromEmbed.php @@ -1,19 +1,19 @@ models = RemoveableGptCollection::make($models); + $this->models = RemoveableEmbedCollection::make($models); } /** @@ -36,7 +36,7 @@ public function __construct($models) public function handle() { if ($this->models->isNotEmpty()) { - $this->models->first()->gptableUsing()->delete($this->models); + $this->models->first()->embeddableUsing()->delete($this->models); } } @@ -44,21 +44,21 @@ public function handle() * Restore a queueable collection instance. * * @param \Illuminate\Contracts\Database\ModelIdentifier $value - * @return \Vormkracht10\LaravelGpt\Jobs\RemoveableGptCollection + * @return \Vormkracht10\Embedding\Jobs\RemoveableEmbedCollection */ protected function restoreCollection($value) { if (! $value->class || count($value->id) === 0) { - return new RemoveableGptCollection; + return new RemoveableEmbedCollection; } - return new RemoveableGptCollection( + return new RemoveableEmbedCollection( collect($value->id)->map(function ($id) use ($value) { return tap(new $value->class, function ($model) use ($id) { $model->setKeyType( is_string($id) ? 'string' : 'int' )->forceFill([ - $model->getGptKeyName() => $id, + $model->getEmbedKeyName() => $id, ]); }); }) diff --git a/src/Jobs/RemoveableEmbedCollection.php b/src/Jobs/RemoveableEmbedCollection.php new file mode 100644 index 0000000..72480a7 --- /dev/null +++ b/src/Jobs/RemoveableEmbedCollection.php @@ -0,0 +1,24 @@ +isEmpty()) { + return []; + } + + return in_array(Embeddable::class, class_uses_recursive($this->first())) + ? $this->map->getEmbedKey()->all() + : parent::getQueueableIds(); + } +} diff --git a/src/Jobs/RemoveableGptCollection.php b/src/Jobs/RemoveableGptCollection.php deleted file mode 100644 index 337be1f..0000000 --- a/src/Jobs/RemoveableGptCollection.php +++ /dev/null @@ -1,24 +0,0 @@ -isEmpty()) { - return []; - } - - return in_array(Gptable::class, class_uses_recursive($this->first())) - ? $this->map->getGptKey()->all() - : parent::getQueueableIds(); - } -} diff --git a/src/ModelObserver.php b/src/ModelObserver.php index 68c3112..65c92ac 100644 --- a/src/ModelObserver.php +++ b/src/ModelObserver.php @@ -1,6 +1,6 @@ usingSoftDeletes = Config::get('gpt.soft_delete', false); + $this->usingSoftDeletes = Config::get('embed.soft_delete', false); } /** @@ -82,17 +82,17 @@ public static function syncingDisabledFor($class) */ public function saved($model) { - if (! $this->forceSaving && ! $model->gptIndexShouldBeUpdated()) { + if (! $this->forceSaving && ! $model->embedIndexShouldBeUpdated()) { return; } - if (! $model->shouldBeGptable()) { - $model->ungptable(); + if (! $model->shouldBeEmbeddable()) { + $model->unembeddable(); return; } - $model->gptable(); + $model->embeddable(); } /** @@ -112,7 +112,7 @@ public function deleted($model) $this->saved($model); }); } else { - $model->ungptable(); + $model->unembeddable(); } } @@ -128,7 +128,7 @@ public function forceDeleted($model) return; } - $model->ungptable(); + $model->unembeddable(); } /** diff --git a/tests/Pest.php b/tests/Pest.php index a540556..b9b0606 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -1,5 +1,5 @@ in(__DIR__); diff --git a/tests/TestCase.php b/tests/TestCase.php index 7daa09e..087dcc7 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,10 +1,10 @@ 'Vormkracht10\\LaravelGpt\\Database\\Factories\\'.class_basename($modelName).'Factory' + fn (string $modelName) => 'Vormkracht10\\Embedding\\Database\\Factories\\'.class_basename($modelName).'Factory' ); } protected function getPackageProviders($app) { return [ - LaravelGptServiceProvider::class, + EmbeddingServiceProvider::class, ]; } @@ -29,7 +29,7 @@ public function getEnvironmentSetUp($app) config()->set('database.default', 'testing'); /* - $migration = include __DIR__.'/../database/migrations/create_laravel-gpt_table.php.stub'; + $migration = include __DIR__.'/../database/migrations/create_laravel-embed_table.php.stub'; $migration->up(); */ }