2
2
3
3
namespace Borah \KnowledgeBase \Traits ;
4
4
5
+ use Borah \KnowledgeBase \Client \KnowledgeBaseClient ;
5
6
use Borah \KnowledgeBase \DTO \KnowledgeBaseQueryResponse ;
6
7
use Borah \KnowledgeBase \DTO \KnowledgeEmbeddingText ;
7
8
use Borah \KnowledgeBase \DTO \KnowledgeInsertItem ;
8
9
use Borah \KnowledgeBase \Facades \KnowledgeBase ;
9
10
use Illuminate \Database \Eloquent \Model ;
10
- use Illuminate \Database \Eloquent \Relations \MorphOne ;
11
+ use Illuminate \Database \Eloquent \Relations \MorphMany ;
11
12
use function Illuminate \Events \queueable ;
12
13
13
14
trait BelongsToKnowledgeBase
@@ -27,33 +28,60 @@ public static function bootBelongsToKnowledgeBase()
27
28
}));
28
29
}
29
30
30
- public function knowledgeBaseId (): MorphOne
31
+ public function knowledgeBaseChunks (): MorphMany
31
32
{
32
- return $ this ->morphOne (config ('knowledge_base.models.knowledge_base_id ' ), 'model ' );
33
+ return $ this ->morphMany (config ('knowledge_base.models.knowledge_base_chunk ' ), 'model ' );
34
+ }
35
+
36
+ public function knowledgeBasePayload (): array
37
+ {
38
+ return [];
33
39
}
34
40
35
41
/**
36
42
* @return KnowledgeInsertItem[]
37
43
*/
38
44
public function knowledgeInsertItems (): array
39
45
{
40
- $ knowledgeBaseId = $ this ->knowledgeBaseId ?? $ this ->knowledgeBaseId ()->create ();
41
46
$ texts = $ this ->getEmbeddingsTexts ();
42
- if (! is_array ($ texts )) {
47
+ if (!is_array ($ texts )) {
43
48
$ texts = [$ texts ];
44
49
}
45
50
46
- return collect ($ texts )
47
- ->map (fn (KnowledgeEmbeddingText $ text ) => new KnowledgeInsertItem (
48
- id: $ knowledgeBaseId ->id ,
51
+ $ items = [];
52
+ $ existingChunks = $ this ->knowledgeBaseChunks ()->get ()->sortBy ('order ' );
53
+ foreach ($ texts as $ i => $ text ) {
54
+ $ chunk = $ existingChunks [$ i ] ?? $ this ->knowledgeBaseChunks ()->create ([
55
+ 'text ' => $ text ->text ,
56
+ 'order ' => $ i ,
57
+ ]);
58
+
59
+ if (!$ chunk ->wasRecentlyCreated && $ chunk ->text !== $ text ->text ) {
60
+ $ chunk ->update (['text ' => $ text ->text ]);
61
+ }
62
+
63
+ $ items [] = new KnowledgeInsertItem (
64
+ id: $ chunk ->id ,
49
65
entity: $ text ->entity ,
50
66
text: $ text ->text ,
51
67
payload: [
52
- ...$ this ->toArray (),
68
+ ...$ this ->knowledgeBasePayload (),
53
69
'original_record_id ' => $ this ->getKey (),
54
70
],
55
- ))
56
- ->toArray ();
71
+ );
72
+ }
73
+
74
+ $ chunksToDelete = $ this ->knowledgeBaseChunks ()
75
+ ->where ('order ' , '>= ' , count ($ texts ))
76
+ ->select ('id ' , 'order ' )
77
+ ->get ();
78
+ $ client = new KnowledgeBaseClient ();
79
+ foreach ($ chunksToDelete as $ chunk ) {
80
+ $ client ->destroy ($ chunk ->id );
81
+ $ chunk ->delete ();
82
+ }
83
+
84
+ return $ items ;
57
85
}
58
86
59
87
public static function searchInKnowledgeBase (string $ query , int $ k = 10 , ?array $ where = null ): KnowledgeBaseQueryResponse
0 commit comments