From 0bfed835b762c101fb2b9e84b016b20f722c136f Mon Sep 17 00:00:00 2001 From: Alfred Nutile Date: Sat, 20 Jul 2024 09:25:54 -0400 Subject: [PATCH] ok fix up some things thanksto stan --- app/Domains/Chat/MetaDataDto.php | 1 + .../Documents/Transformers/CSVTransformer.php | 15 +- app/Domains/EmailParser/EmailClient.php | 3 +- app/Domains/EmailParser/MailDto.php | 4 +- app/Domains/Sources/BaseSource.php | 16 ++ app/Domains/Sources/EmailSource.php | 173 ++++++++---------- app/Helpers/ChatHelperTrait.php | 36 ++++ .../AssistantEmailBoxSourceController.php | 1 + app/Http/Controllers/BaseSourceController.php | 4 + app/Http/Controllers/ChatController.php | 2 +- .../Sources/EmailBoxSourceController.php | 1 + .../Sources/FeedSourceController.php | 1 + .../Sources/GoogleSheetSourceController.php | 1 + .../Sources/JsonSourceController.php | 1 + .../Sources/SiteMapSourceController.php | 1 + .../Sources/WebPageSourceController.php | 1 + .../Sources/WebhookSourceController.php | 1 + app/Jobs/ChunkDocumentJob.php | 38 ++++ app/Models/Source.php | 10 + app/Providers/AppServiceProvider.php | 1 - database/factories/SourceFactory.php | 3 + .../2024_07_20_130256_add_chat_to_soruces.php | 30 +++ tests/Feature/EmailSourceTest.php | 47 ++--- .../WebhookSourceControllerTest.php | 2 + tests/Feature/Jobs/ChunkDocumentJobTest.php | 18 ++ tests/fixtures/.DS_Store | Bin 14340 -> 14340 bytes 26 files changed, 280 insertions(+), 131 deletions(-) create mode 100644 app/Helpers/ChatHelperTrait.php create mode 100644 app/Jobs/ChunkDocumentJob.php create mode 100644 database/migrations/2024_07_20_130256_add_chat_to_soruces.php create mode 100644 tests/Feature/Jobs/ChunkDocumentJobTest.php diff --git a/app/Domains/Chat/MetaDataDto.php b/app/Domains/Chat/MetaDataDto.php index da07d549..58bb6cd2 100644 --- a/app/Domains/Chat/MetaDataDto.php +++ b/app/Domains/Chat/MetaDataDto.php @@ -15,6 +15,7 @@ public function __construct( public mixed $date_range = '', public mixed $input = '', public mixed $driver = '', + public mixed $source = '', public mixed $reference_collection_id = '', ) { diff --git a/app/Domains/Documents/Transformers/CSVTransformer.php b/app/Domains/Documents/Transformers/CSVTransformer.php index 85c5c604..12934481 100644 --- a/app/Domains/Documents/Transformers/CSVTransformer.php +++ b/app/Domains/Documents/Transformers/CSVTransformer.php @@ -26,7 +26,6 @@ public function handle(Document $document): array $filePath = $this->document->pathToFile(); - //$filePath = null, string $disk = null, string $readerType = null $collection = (new DocumentsImport()) ->toCollection($filePath, null, $this->readerType); @@ -47,6 +46,20 @@ public function handle(Document $document): array return remove_ascii($key.': '.$item); })->implode("\n"); + /** + * @TODO + * We have the text but what does the user want to do with the text + * 1) Here we should have a source with a chat_id or make the chat id + * 2) this becomes a message (that is a lot of them?) + * 3) then the LLM gets the sources prompt and sees what the user wants to do with the data. + * 4) Example "Take these dates and save them to the document start and end data then save the content to the document as an event" + * Then tag the document by the Region seen in the data (or hard coded in the prompt) + * 5) The Prompt using OrchestrateV2 should take the Chat and Message and start building out the results + * this will update or create a document + * this will find start_date and end_date new fields in a document + * this will tag the document Region: Foobar + * NOTE: We already have date_range so bummer it is created_at + */ $file_name = 'row_'.$rowNumber.'_'.str($document->file_path)->beforeLast('.')->toString().'.txt'; Storage::disk('collections') diff --git a/app/Domains/EmailParser/EmailClient.php b/app/Domains/EmailParser/EmailClient.php index 8fc9b57f..3604487e 100644 --- a/app/Domains/EmailParser/EmailClient.php +++ b/app/Domains/EmailParser/EmailClient.php @@ -35,7 +35,7 @@ public function setConfig(array $config): self * @throws \Webklex\PHPIMAP\Exceptions\MessageNotFoundException * @throws \Webklex\PHPIMAP\Exceptions\RuntimeException */ - public function handle(CredentialsDto $credentials, bool $delete = true): array + public function handle(CredentialsDto $credentials, bool $delete = false): array { $mail = []; @@ -107,6 +107,7 @@ public function handle(CredentialsDto $credentials, bool $delete = true): array 'subject' => $message->getSubject(), 'date' => $message->getDate()->toString(), 'header' => $message->getHeader()->raw, + 'email_message' => $message, ]); $mail[] = $messageDto; diff --git a/app/Domains/EmailParser/MailDto.php b/app/Domains/EmailParser/MailDto.php index db3b86b1..307f5634 100644 --- a/app/Domains/EmailParser/MailDto.php +++ b/app/Domains/EmailParser/MailDto.php @@ -3,6 +3,7 @@ namespace App\Domains\EmailParser; use Spatie\LaravelData\Data; +use Webklex\PHPIMAP\Message; class MailDto extends Data { @@ -12,7 +13,8 @@ public function __construct( public ?string $to, public ?string $body, public ?string $header, - public ?string $date + public ?string $date, + public ?Message $email_message = null ) { } diff --git a/app/Domains/Sources/BaseSource.php b/app/Domains/Sources/BaseSource.php index 0892bf1b..ad1d044a 100644 --- a/app/Domains/Sources/BaseSource.php +++ b/app/Domains/Sources/BaseSource.php @@ -4,6 +4,7 @@ use App\Domains\Prompts\PromptMerge; use App\Domains\UnStructured\StructuredTypeEnum; +use App\Helpers\ChatHelperTrait; use App\Jobs\DocumentProcessingCompleteJob; use App\Jobs\SummarizeDocumentJob; use App\Jobs\VectorlizeDataJob; @@ -21,6 +22,8 @@ abstract class BaseSource { + use ChatHelperTrait; + public string $batchTitle = 'Chunking Source'; public static string $description = 'Sources are ways we get data into the system. They are the core of the system.'; @@ -215,4 +218,17 @@ protected function getEmailSummary(Document $document): string return $content; } + + public function getSourceFromSlug(string $slug): ?Source + { + $source = Source::where('type', $this->sourceTypeEnum) + ->slug($slug) + ->first(); + + if ($source) { + return $source; + } + + return null; + } } diff --git a/app/Domains/Sources/EmailSource.php b/app/Domains/Sources/EmailSource.php index e6de92ca..1d5091ba 100644 --- a/app/Domains/Sources/EmailSource.php +++ b/app/Domains/Sources/EmailSource.php @@ -2,13 +2,20 @@ namespace App\Domains\Sources; +use App\Domains\Chat\MetaDataDto; +use App\Domains\Documents\StatusEnum; +use App\Domains\Documents\TypesEnum; use App\Domains\EmailParser\MailDto; +use App\Domains\Messages\RoleEnum; +use App\Domains\Prompts\PromptMerge; +use App\Jobs\ChunkDocumentJob; use App\Models\Document; use App\Models\Source; -use App\Models\Transformer; use Facades\App\Domains\EmailParser\Client; -use Facades\App\Domains\Transformers\EmailTransformer; +use Illuminate\Support\Facades\Bus; use Illuminate\Support\Facades\Log; +use Laravel\Prompts\Prompt; +use LlmLaraHub\LlmDriver\LlmDriverFacade; class EmailSource extends BaseSource { @@ -38,7 +45,7 @@ public function handle(Source $source): void return; } - $this->source = $source; + $this->source = $this->checkForChat($source); $this->content = $this->mailDto->getContent(); @@ -46,102 +53,72 @@ public function handle(Source $source): void $this->meta_data = $this->mailDto->toArray(); - $this->transformers = $source->transformers; - Log::info('[LaraChain] - Running Email Source'); - /** - * @TODO - * I missed the point here. I just need to keep making tools work - * and the prompt the user gives in the Source - * let it do the work. - */ - try { - /** - * @TODO - * This turns the email into a document but what if the user wants to do something with the - * data in the email. Like Parse URLs or Recipe ideas etc - * The Prompt of the Source should drive all of this - */ - $baseSource = EmailTransformer::transform(baseSource: $this); - /** - * @NOTE - * Examples - * Example One: Maybe there is 1 transformer to make a reply to the email - * Transformer 1 of 1 ReplyTo Email - * Take the email - * Use Collection as voice - * Make reply to email - * The Transformer as an Output attached to it and the reply is sent. - * - * Example Two: CRM Transformer - * Take the email and make document (Type Email) and chunks from the email - * After that take the content and make who is it to, who is it from - * and make Documents for each for those of type Contact - * Relate those to the document (Type Email) - * and now there are relations for later use - * - * @TODO - * some transformers assume they are never 0 in the chain - * like CRM assumes the one before was EmailTransformer - * and the document is set - */ - Log::info("[LaraChain] - Source has Transformers let's figure out which one to run"); - - foreach ($source->transformers as $transformerChainLink) { - $class = '\\App\\Domains\\Transformers\\'.$transformerChainLink->type->name; - if (class_exists($class)) { - $facade = '\\Facades\\App\\Domains\\Transformers\\'.$transformerChainLink->type->name; - $baseSource = $facade::transform($this); - } else { - Log::info('[LaraChain] - No Class found ', [ - 'class' => $class, - ]); - } - } - $this->batchTransformedSource($baseSource, $source); - - } catch (\Exception $e) { - Log::error('[LaraChain] - Error running Email Source', [ - 'error' => $e->getMessage(), - ]); - } - - } - - public function getSourceFromSlug(string $slug): ?Source - { - $source = Source::where('type', $this->sourceTypeEnum) - ->slug($slug) - ->first(); - - if ($source) { - return $source; - } - - return null; - } - - protected function getSummarizeDocumentPrompt(): string - { - if (str($this->source->details)->contains('[CONTEXT]')) { - return $this->source->details; - } - - return <<<'PROMPT' - -The following content is from an email. I would like you to summarize it with the following format. - -To: **TO HERE** -From: **From Here** -Subject: **Subject Here** -Body: -**Summary Here** - - -** CONTEXT IS BELOW THIS LINE** -[CONTEXT] -PROMPT; - + //use the users source prompt to create this next step + //track the results in a chat_id thread + //and as a message? + //then using the source the results will do something with the content + // and then delete the email + // but we can leave it if it returns false? + // still too much coding there how do I let the tool do it. + + $prompt = PromptMerge::merge( + ['[CONTEXT]'], + [$this->content], + $source->getPrompt() + ); + + $chat = $source->chat; + + $chat->addInput( + message: $prompt, + role: RoleEnum::User, + show_in_thread: true, + meta_data: MetaDataDto::from([ + 'driver' => $source->getDriver(), + 'source' => $source->title, + ]), + ); + + $results = LlmDriverFacade::driver( + $source->getDriver() + )->completion($prompt); + + $chat->addInput( + message: $results->content, + role: RoleEnum::Assistant, + show_in_thread: true, + meta_data: MetaDataDto::from([ + 'driver' => $source->getDriver(), + 'source' => $source->title, + ]), + ); + + //@TODO how to look for false + // surface this "power" into the UI. + // tag or store the fact we checked this emails + + $document = Document::updateOrCreate([ + 'source_id' => $source->id, + 'type' => TypesEnum::Email, + 'subject' => $this->mailDto->subject, + 'collection_id' => $source->collection_id, + ], [ + 'summary' => $results->content, + 'meta_data' => $this->mailDto->toArray(), + 'original_content' => $this->mailDto->body, + 'status_summary' => StatusEnum::Pending, + 'status' => StatusEnum::Pending, + ]); + + Bus::batch([new ChunkDocumentJob($document)]) + ->name("Processing Email {$this->mailDto->subject}") + ->allowFailures() + ->dispatch(); + + //should we delete the email? + // right now it gets set to seen + // on the MailDto we have options } } diff --git a/app/Helpers/ChatHelperTrait.php b/app/Helpers/ChatHelperTrait.php new file mode 100644 index 00000000..1ac3c767 --- /dev/null +++ b/app/Helpers/ChatHelperTrait.php @@ -0,0 +1,36 @@ +chat_id) { + //@NOTE should I go to Source as the chatable? + $chat = Chat::create([ + 'chatable_id' => $source->collection_id, + 'chatable_type' => Collection::class, + 'user_id' => $source->collection->team?->user_id, + ]); + $source->update([ + 'chat_id' => $chat->id, + ]); + } + + return $source->refresh(); + } + + public function getUserId(Collection $collection): ?int + { + if (auth()->check()) { + return auth()->user()->id; + } + + return $collection->team?->user_id; + } +} diff --git a/app/Http/Controllers/AssistantEmailBoxSourceController.php b/app/Http/Controllers/AssistantEmailBoxSourceController.php index ed03ea87..ef32e200 100644 --- a/app/Http/Controllers/AssistantEmailBoxSourceController.php +++ b/app/Http/Controllers/AssistantEmailBoxSourceController.php @@ -31,6 +31,7 @@ protected function makeSource(array $validated, Collection $collection): void 'recurring' => $validated['recurring'], 'active' => $validated['active'], 'collection_id' => $collection->id, + 'user_id' => $this->getUserId($collection), 'type' => $this->sourceTypeEnum, 'slug' => str(Str::random(12))->remove('+')->toString(), 'meta_data' => [], diff --git a/app/Http/Controllers/BaseSourceController.php b/app/Http/Controllers/BaseSourceController.php index 3f644c2d..7cf64545 100644 --- a/app/Http/Controllers/BaseSourceController.php +++ b/app/Http/Controllers/BaseSourceController.php @@ -4,6 +4,7 @@ use App\Domains\Recurring\RecurringTypeEnum; use App\Domains\Sources\SourceTypeEnum; +use App\Helpers\ChatHelperTrait; use App\Http\Resources\CollectionResource; use App\Http\Resources\DocumentResource; use App\Http\Resources\FilterResource; @@ -16,6 +17,8 @@ class BaseSourceController extends Controller { + use ChatHelperTrait; + protected SourceTypeEnum $sourceTypeEnum = SourceTypeEnum::WebSearchSource; protected string $edit_path = 'Sources/WebSource/Edit'; @@ -60,6 +63,7 @@ protected function makeSource(array $validated, Collection $collection): void 'active' => $validated['active'], 'collection_id' => $collection->id, 'type' => $this->sourceTypeEnum, + 'user_id' => $this->getUserId($collection), 'meta_data' => [ 'driver' => 'brave', 'limit' => 5, diff --git a/app/Http/Controllers/ChatController.php b/app/Http/Controllers/ChatController.php index d297022f..bb2ad09e 100644 --- a/app/Http/Controllers/ChatController.php +++ b/app/Http/Controllers/ChatController.php @@ -58,7 +58,7 @@ function ($item) { 'audiences' => AudienceResource::collection(Audience::all()), 'system_prompt' => $collection->systemPrompt(), 'settings' => [ - 'supports_functions' => LlmDriverFacade::driver($chat->getDriver())->hasFunctions(), + 'supports_functions' => LlmDriverFacade::driver($chat->getDriver())->hasFunctions(), ], 'messages' => MessageResource::collection($chat->latest_messages), ]); diff --git a/app/Http/Controllers/Sources/EmailBoxSourceController.php b/app/Http/Controllers/Sources/EmailBoxSourceController.php index bab4cdad..b39936aa 100644 --- a/app/Http/Controllers/Sources/EmailBoxSourceController.php +++ b/app/Http/Controllers/Sources/EmailBoxSourceController.php @@ -35,6 +35,7 @@ protected function makeSource(array $validated, Collection $collection): void 'details' => $validated['details'], 'recurring' => $validated['recurring'], 'active' => $validated['active'], + 'user_id' => $this->getUserId($collection), 'collection_id' => $collection->id, 'type' => $this->sourceTypeEnum, 'slug' => str(Str::random(12))->remove('+')->toString(), diff --git a/app/Http/Controllers/Sources/FeedSourceController.php b/app/Http/Controllers/Sources/FeedSourceController.php index 9dcdc4de..a19ba614 100644 --- a/app/Http/Controllers/Sources/FeedSourceController.php +++ b/app/Http/Controllers/Sources/FeedSourceController.php @@ -49,6 +49,7 @@ protected function makeSource(array $validated, Collection $collection): void 'title' => $validated['title'], 'details' => $validated['details'], 'recurring' => $validated['recurring'], + 'user_id' => $this->getUserId($collection), 'active' => $validated['active'], 'collection_id' => $collection->id, 'type' => $this->sourceTypeEnum, diff --git a/app/Http/Controllers/Sources/GoogleSheetSourceController.php b/app/Http/Controllers/Sources/GoogleSheetSourceController.php index 13f4b48a..0cec5ef4 100644 --- a/app/Http/Controllers/Sources/GoogleSheetSourceController.php +++ b/app/Http/Controllers/Sources/GoogleSheetSourceController.php @@ -53,6 +53,7 @@ protected function makeSource(array $validated, Collection $collection): void 'recurring' => $validated['recurring'], 'active' => $validated['active'], 'collection_id' => $collection->id, + 'user_id' => $this->getUserId($collection), 'type' => $this->sourceTypeEnum, 'meta_data' => $validated['meta_data'], ]); diff --git a/app/Http/Controllers/Sources/JsonSourceController.php b/app/Http/Controllers/Sources/JsonSourceController.php index 0399d3bb..6c81950e 100644 --- a/app/Http/Controllers/Sources/JsonSourceController.php +++ b/app/Http/Controllers/Sources/JsonSourceController.php @@ -44,6 +44,7 @@ protected function makeSource(array $validated, Collection $collection): void 'recurring' => $validated['recurring'], 'active' => $validated['active'], 'collection_id' => $collection->id, + 'user_id' => $this->getUserId($collection), 'slug' => str(Str::random(16))->toString(), 'type' => $this->sourceTypeEnum, 'meta_data' => json_decode($validated['meta_data'], true, 512), diff --git a/app/Http/Controllers/Sources/SiteMapSourceController.php b/app/Http/Controllers/Sources/SiteMapSourceController.php index 638462ce..85f70d3d 100644 --- a/app/Http/Controllers/Sources/SiteMapSourceController.php +++ b/app/Http/Controllers/Sources/SiteMapSourceController.php @@ -48,6 +48,7 @@ protected function makeSource(array $validated, Collection $collection): void Source::create([ 'title' => $validated['title'], 'details' => $validated['details'], + 'user_id' => $this->getUserId($collection), 'recurring' => $validated['recurring'], 'active' => $validated['active'], 'collection_id' => $collection->id, diff --git a/app/Http/Controllers/Sources/WebPageSourceController.php b/app/Http/Controllers/Sources/WebPageSourceController.php index 65781918..cf2d8abf 100644 --- a/app/Http/Controllers/Sources/WebPageSourceController.php +++ b/app/Http/Controllers/Sources/WebPageSourceController.php @@ -42,6 +42,7 @@ protected function makeSource(array $validated, Collection $collection): void 'active' => $validated['active'], 'collection_id' => $collection->id, 'type' => $this->sourceTypeEnum, + 'user_id' => $this->getUserId($collection), 'meta_data' => $validated['meta_data'], ]); } diff --git a/app/Http/Controllers/Sources/WebhookSourceController.php b/app/Http/Controllers/Sources/WebhookSourceController.php index 6f91a623..1773911c 100644 --- a/app/Http/Controllers/Sources/WebhookSourceController.php +++ b/app/Http/Controllers/Sources/WebhookSourceController.php @@ -34,6 +34,7 @@ protected function makeSource(array $validated, Collection $collection): void 'details' => $validated['details'], 'recurring' => $validated['recurring'], 'active' => $validated['active'], + 'user_id' => $this->getUserId($collection), 'collection_id' => $collection->id, 'slug' => str(Str::random(16))->toString(), 'type' => $this->sourceTypeEnum, diff --git a/app/Jobs/ChunkDocumentJob.php b/app/Jobs/ChunkDocumentJob.php new file mode 100644 index 00000000..643d4528 --- /dev/null +++ b/app/Jobs/ChunkDocumentJob.php @@ -0,0 +1,38 @@ +batch()->cancelled()) { + // Determine if the batch has been cancelled... + return; + } + + } +} diff --git a/app/Models/Source.php b/app/Models/Source.php index 18de9813..400ccf39 100644 --- a/app/Models/Source.php +++ b/app/Models/Source.php @@ -43,6 +43,11 @@ protected static function booted(): void }); } + public function getPrompt(): string + { + return $this->details; + } + public function getChatable(): HasDrivers { return $this->collection->getChatable(); @@ -77,6 +82,11 @@ public function getDriver(): string return $this->collection->getDriver(); } + public function chat(): BelongsTo + { + return $this->belongsTo(Chat::class); + } + public function getEmbeddingDriver(): string { return $this->collection->getEmbeddingDriver(); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 9603aae5..9b0aa424 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -65,7 +65,6 @@ public function boot(): void return false; }); - Feature::define('verification_prompt', function (User $user) { return false; }); diff --git a/database/factories/SourceFactory.php b/database/factories/SourceFactory.php index a0883505..91da122b 100644 --- a/database/factories/SourceFactory.php +++ b/database/factories/SourceFactory.php @@ -4,6 +4,7 @@ use App\Domains\Recurring\RecurringTypeEnum; use App\Domains\Sources\SourceTypeEnum; +use App\Models\Chat; use App\Models\Collection; use Illuminate\Database\Eloquent\Factories\Factory; @@ -23,6 +24,8 @@ public function definition(): array 'title' => $this->faker->name, 'slug' => fake()->word, 'collection_id' => Collection::factory(), + 'user_id' => null, + 'chat_id' => Chat::factory(), 'details' => $this->faker->sentence, // 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. 'recurring' => RecurringTypeEnum::Daily, 'active' => true, diff --git a/database/migrations/2024_07_20_130256_add_chat_to_soruces.php b/database/migrations/2024_07_20_130256_add_chat_to_soruces.php new file mode 100644 index 00000000..e45050ea --- /dev/null +++ b/database/migrations/2024_07_20_130256_add_chat_to_soruces.php @@ -0,0 +1,30 @@ +foreignIdFor(\App\Models\Chat::class)->nullable(); + $table->foreignIdFor(\App\Models\User::class)->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('sources', function (Blueprint $table) { + $table->dropColumn('chat_id'); + $table->dropColumn('user_id'); + }); + } +}; diff --git a/tests/Feature/EmailSourceTest.php b/tests/Feature/EmailSourceTest.php index 81b13dab..d23c7940 100644 --- a/tests/Feature/EmailSourceTest.php +++ b/tests/Feature/EmailSourceTest.php @@ -2,17 +2,14 @@ namespace Tests\Feature; -use App\Domains\Documents\TypesEnum; use App\Domains\EmailParser\MailDto; use App\Domains\Sources\SourceTypeEnum; -use App\Domains\Transformers\TypeEnum; -use App\Domains\UnStructured\StructuredTypeEnum; -use App\Models\Document; use App\Models\Source; -use App\Models\Transformer; use Facades\App\Domains\EmailParser\Client; use Facades\App\Domains\Sources\EmailSource; use Illuminate\Support\Facades\Bus; +use LlmLaraHub\LlmDriver\LlmDriverFacade; +use LlmLaraHub\LlmDriver\Responses\CompletionResponse; use Tests\TestCase; class EmailSourceTest extends TestCase @@ -46,6 +43,12 @@ public function test_batches() 'type' => SourceTypeEnum::EmailSource, ]); + LlmDriverFacade::shouldReceive('driver->completion')->once()->andReturn( + CompletionResponse::from([ + 'content' => 'foo bar', + ]) + ); + $body = <<<'BODY' Quis ea esse velit id id eu consectetur deserunt exercitation exercitation. Nisi aliqua ipsum fugiat laborum aliquip nostrud eu tempor non cillum Lorem non dolor proident sunt. Irure commodo aliqua reprehenderit deserunt sint irure in excepteur quis eiusmod ullamco aliquip. Dolore tempor ea non ut.Quis ea esse velit id id eu consectetur deserunt exercitation exercitation. Nisi aliqua ipsum fugiat laborum aliquip nostrud eu tempor non cillum Lorem non dolor proident sunt. Irure commodo aliqua reprehenderit deserunt sint irure in excepteur quis eiusmod ullamco aliquip. Dolore tempor ea non ut. Quis ea esse velit id id eu consectetur deserunt exercitation exercitation. Nisi aliqua ipsum fugiat laborum aliquip nostrud eu tempor non cillum Lorem non dolor proident sunt. Irure commodo aliqua reprehenderit deserunt sint irure in excepteur quis eiusmod ullamco aliquip. Dolore tempor ea non ut. @@ -69,8 +72,6 @@ public function test_batches() $this->assertDatabaseCount('documents', 1); - $this->assertDatabaseCount('document_chunks', 8); - Bus::assertBatchCount(1); } @@ -87,7 +88,7 @@ public function test_run() $source->run(); } - public function test_related_tranformers() + public function tests_creates_chat_and_message() { Bus::fake(); $source = Source::factory()->create([ @@ -95,6 +96,12 @@ public function test_related_tranformers() 'type' => SourceTypeEnum::EmailSource, ]); + LlmDriverFacade::shouldReceive('driver->completion')->once()->andReturn( + CompletionResponse::from([ + 'content' => 'foo bar', + ]) + ); + $body = <<<'BODY' Quis ea esse velit id id eu consectetur deserunt exercitation exercitation. Nisi aliqua ipsum fugiat laborum aliquip nostrud eu tempor non cillum Lorem non dolor proident sunt. Irure commodo aliqua reprehenderit deserunt sint irure in excepteur quis eiusmod ullamco aliquip. Dolore tempor ea non ut.Quis ea esse velit id id eu consectetur deserunt exercitation exercitation. Nisi aliqua ipsum fugiat laborum aliquip nostrud eu tempor non cillum Lorem non dolor proident sunt. Irure commodo aliqua reprehenderit deserunt sint irure in excepteur quis eiusmod ullamco aliquip. Dolore tempor ea non ut. Quis ea esse velit id id eu consectetur deserunt exercitation exercitation. Nisi aliqua ipsum fugiat laborum aliquip nostrud eu tempor non cillum Lorem non dolor proident sunt. Irure commodo aliqua reprehenderit deserunt sint irure in excepteur quis eiusmod ullamco aliquip. Dolore tempor ea non ut. @@ -105,17 +112,6 @@ public function test_related_tranformers() BODY; - $transformer = Transformer::factory()->create( - [ - 'transformable_id' => $source->id, - 'transformable_type' => Source::class, - 'parent_id' => null, - 'last_run' => null, - 'active' => true, - 'type' => TypeEnum::CrmTransformer, - ] - ); - $dto = MailDto::from([ 'to' => 'info+12345@llmassistant.io', 'from' => 'foo@var.com', @@ -127,17 +123,12 @@ public function test_related_tranformers() $emailSource = new \App\Domains\Sources\EmailSource(); $emailSource->setMailDto($dto)->handle($source); - $this->assertDatabaseCount('documents', 3); + $this->assertDatabaseCount('documents', 1); + $this->assertDatabaseCount('chats', 1); + $this->assertDatabaseCount('messages', 2); - $this->assertDatabaseCount('document_chunks', 10); + $this->assertNotNull($source->chat_id); Bus::assertBatchCount(1); - - $documentTo = Document::whereType(TypesEnum::Contact)->exists(); - $this->assertTrue($documentTo); - $documentTo = Document::where('child_type', StructuredTypeEnum::EmailFrom)->exists(); - $this->assertTrue($documentTo); - $documentTo = Document::where('child_type', StructuredTypeEnum::EmailTo)->exists(); - $this->assertTrue($documentTo); } } diff --git a/tests/Feature/Http/Controllers/WebhookSourceControllerTest.php b/tests/Feature/Http/Controllers/WebhookSourceControllerTest.php index 954fa5b9..c4d0baae 100644 --- a/tests/Feature/Http/Controllers/WebhookSourceControllerTest.php +++ b/tests/Feature/Http/Controllers/WebhookSourceControllerTest.php @@ -39,6 +39,8 @@ public function test_store(): void $this->assertEquals(SourceTypeEnum::WebhookSource, $source->type); $this->assertEquals('foobar', $source->secrets['token']); + + $this->assertNotNull($source->user_id); } public function test_update() diff --git a/tests/Feature/Jobs/ChunkDocumentJobTest.php b/tests/Feature/Jobs/ChunkDocumentJobTest.php new file mode 100644 index 00000000..a5f716d7 --- /dev/null +++ b/tests/Feature/Jobs/ChunkDocumentJobTest.php @@ -0,0 +1,18 @@ +get('/'); + + $response->assertStatus(200); + } +} diff --git a/tests/fixtures/.DS_Store b/tests/fixtures/.DS_Store index 45af69f5d6bf2bebe08cdf94ff12fb1e21466fc4..5fb14f776abfccb74c3a7b1507e559338be85783 100644 GIT binary patch delta 1449 zcmds$OKjXk7{}-Dq}lPBHk0RUQtdWvN(H2kZ7DQ`ywf6*Hce>~@@Q%B#?xfLYcFf> zCMk!#1l0D(BJn5!L_xfyQV}6QoRARWz(Yb2QZGmd2@r4r0Vkl0?WG_D2gD5@#{RyU z??3a+|L2w5O77Cr4O_IIGdWv&emZ>_T2=MBni$pN#x>lCPsHz>l5?(8zS6um%?h44 zCT!D}MRCCNg*WAkC4Wqw7Bilk_Xl0OkacFvrSVF(yqhV&?y?*D7 zo!tYs4If$CP|ND-8w_JcTEg+=DJk+3i_-EJrcG~7IF@wgCyUaP8C#4yW>(Zyb?f?C zT`k+d6TFqOb~;ta$omS?UkvU$)aZmLSWjc%Wx~^I68EQ{6$A};fStcvwG4c$#Kwc$pk$1`aRG%fhX}4 zF5-2(fj99EKEQ|g2%q6=e1mWC6Rv3WTBFvaHEUc;Xvyf{8Y&G;UTq}&&~}!4>RY$l zUNM)k-3%dG;ctmf8S&fWL;sEFq@!?GI%Tjb#j76H?(I+^DnaLd!(i2l zTz#!|DAB@=9-~hW{uoBW#RG#%D&Ua*8z9QBB$A~Dv?!Z9umfrA#vWyLH+s<*+I?7= zJ&L24#&Ko%NoDy0?tzUg94ulPr$g5t3|&8mG9JbwcodK00-nS3cmXfsCA^GFe{pyC m&+b+eg0};ESLa)vttq#man)$+rg!|_?f<)3wi-+S68jC_3QHOQ delta 1476 zcmds#Uu+ab9LMLog?9Hw=^X9#?s}`#6cE!=&uS1-DlPqk2&DwB+#kVauRFG5w|nR9 z_FAfVFZEA+F>p~s;zJSCH$!MhNQe^UMG~I$66Hk`GSj;!4ZrhDg3>3CB$)Z$W8Tx4yAS)k5?E{a7d+qB&zR#TVV`owlbc z8_R+(j2B%|u$^PP!$CTloT+%|@+RRcqm9wqa9;PLG@NGGhhP zJI!R5Rn4z#?$Gt;y~( z%+!KLPw%99x*WU{J5W#VZlQW+sxUVvwK(1|!RDoUdcRChvSz>F?HVzKTkwnWJ;tPttasj^Y5FSS(O6hNqNh~$wOTzFX{o5K zfeZIX_^+uEl_bbkvXcyu6cMCEPLVgrS@Iz{PcD(GKLdlMbnjgIIhKXLNde`RgY)Z zRP$MWgm$WuA+|mUx6*B@q=z*IVOL_iDuHE+AJSx^SCdq-h9K-p?9fz(AlOCwG|4Ah zS8E@Q#iRW?rHn{i{VsbG!>WXgss9Fr>e<*sl?W2pf-Y&bXLK+6up7@{4+ilZ4qyz2 zr0H4Ya2zKvi5Y47EG*bqz#>lK6)fX*>HAxFTe|)(-oyJ?!8x4A1>gTG_-u`%``0*% f&pk_5kH#-FuF{Tvb^0IG{~yJ#G_E!!e{cE|EWKK@