speaky 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +0 -2
- data/lib/speaky/concern.rb +1 -21
- data/lib/speaky/vectorstore_base.rb +10 -6
- data/lib/speaky/vectorstore_qdrant.rb +37 -24
- data/lib/speaky/version.rb +1 -1
- data/lib/speaky.rb +25 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6be1d021d8ebe259d6aa37fe46dc536e8be03b0e4b19309ad06733625bb91ff
|
4
|
+
data.tar.gz: 5a5b658cd9ea7878362d436cee77b322be437e0a6bca88db844eb56cd06719af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28e149649e103d758b87dbb73b3417f1fbdf8e0e73838b24f602fc17204fc2a972fee798eed57aa9c0b92d30ffbeae18047eaa845e248af1355dce1f72b006ed
|
7
|
+
data.tar.gz: ca90c2c737d2f2e151c2f35a8b2b429f116aeb386c02951aa87e119635d0f06cf86fbd1ab9dc4764014d5c830998d6fd9299dee00d4877282fcaa567f4e961dd
|
data/README.md
CHANGED
@@ -62,8 +62,6 @@ class MyModel < ApplicationRecord
|
|
62
62
|
end
|
63
63
|
|
64
64
|
# Add any callbacks that should update the model instance data in the vector store.
|
65
|
-
after_create :create_for_speaky
|
66
|
-
after_update :update_for_speaky
|
67
65
|
after_save :save_for_speaky
|
68
66
|
after_destroy :destroy_for_speaky
|
69
67
|
end
|
data/lib/speaky/concern.rb
CHANGED
@@ -11,7 +11,7 @@ module Speaky
|
|
11
11
|
self.to_json
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def save_for_speaky
|
15
15
|
begin
|
16
16
|
Speaky.vectorstore.add(self.id, self.as_speaky)
|
17
17
|
rescue StandardError => e
|
@@ -21,16 +21,6 @@ module Speaky
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
def update_for_speaky
|
25
|
-
begin
|
26
|
-
Speaky.vectorstore.update(self.id, self.as_speaky)
|
27
|
-
rescue StandardError => e
|
28
|
-
Rails.logger.error(e)
|
29
|
-
errors.add(:base, 'Failed to update for speaky')
|
30
|
-
raise ActiveRecord::Rollback
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
24
|
def destroy_for_speaky
|
35
25
|
begin
|
36
26
|
Speaky.vectorstore.remove(self.id)
|
@@ -40,15 +30,5 @@ module Speaky
|
|
40
30
|
raise ActiveRecord::Rollback
|
41
31
|
end
|
42
32
|
end
|
43
|
-
|
44
|
-
def save_for_speaky
|
45
|
-
ActiveRecord::Base.transaction do
|
46
|
-
if self.new_record?
|
47
|
-
create_for_speaky
|
48
|
-
else
|
49
|
-
update_for_speaky
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
33
|
end
|
54
34
|
end
|
@@ -12,24 +12,28 @@ module Speaky
|
|
12
12
|
|
13
13
|
# Add a vector to the vectorstore.
|
14
14
|
# NOTE: If the vector already exists, it will be updated.
|
15
|
+
# Returns a boolean.
|
15
16
|
def add(id, data)
|
16
17
|
raise NotImplementedError
|
17
18
|
end
|
18
19
|
|
19
|
-
# Update a vector in the vectorstore.
|
20
|
-
# NOTE: If the vector does not exist, it will be added.
|
21
|
-
def update(id, data)
|
22
|
-
raise NotImplementedError
|
23
|
-
end
|
24
|
-
|
25
20
|
# Remove a vector from the vectorstore.
|
26
21
|
# NOTE: If the vector does not exist, it will be ignored.
|
22
|
+
# Returns a boolean.
|
27
23
|
def remove(id)
|
28
24
|
raise NotImplementedError
|
29
25
|
end
|
30
26
|
|
27
|
+
# Query the vectorstore with a question.
|
28
|
+
# Returns a string.
|
31
29
|
def query(question)
|
32
30
|
raise NotImplementedError
|
33
31
|
end
|
32
|
+
|
33
|
+
# Reset the vectorstore.
|
34
|
+
# Returns a boolean.
|
35
|
+
def reset
|
36
|
+
raise NotImplementedError
|
37
|
+
end
|
34
38
|
end
|
35
39
|
end
|
@@ -18,26 +18,8 @@ module Speaky
|
|
18
18
|
api_key: @config[:api_key]
|
19
19
|
)
|
20
20
|
|
21
|
-
# create collection
|
22
|
-
|
23
|
-
if !collections_get || collections_get.dig('status') != 'ok'
|
24
|
-
collections_create = @client.collections.create(
|
25
|
-
collection_name: @config[:collection_name],
|
26
|
-
vectors: {
|
27
|
-
distance: "Cosine",
|
28
|
-
size: 1536
|
29
|
-
}
|
30
|
-
)
|
31
|
-
if !collections_create || collections_create.dig('status') != 'ok'
|
32
|
-
raise 'Failed to create collection'
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# create index for field "id" in collection
|
37
|
-
collections_create_index = @client.collections.create_index(collection_name: @config[:collection_name], field_name: 'id', field_schema: 'keyword')
|
38
|
-
if !collections_create_index || collections_create_index.dig('status') != 'ok'
|
39
|
-
raise 'Failed to create index for field "id" on collection'
|
40
|
-
end
|
21
|
+
# create collection
|
22
|
+
create_collection
|
41
23
|
end
|
42
24
|
|
43
25
|
def add(id, data)
|
@@ -64,10 +46,6 @@ module Speaky
|
|
64
46
|
true
|
65
47
|
end
|
66
48
|
|
67
|
-
def update(id, data)
|
68
|
-
add(id, data)
|
69
|
-
end
|
70
|
-
|
71
49
|
def remove(id)
|
72
50
|
points_delete = @client.points.delete(
|
73
51
|
collection_name: @config[:collection_name],
|
@@ -98,5 +76,40 @@ module Speaky
|
|
98
76
|
|
99
77
|
points_search.dig('result').first.dig('payload', 'content')
|
100
78
|
end
|
79
|
+
|
80
|
+
def reset
|
81
|
+
collections_delete = @client.collections.delete(collection_name: @config[:collection_name])
|
82
|
+
if !collections_delete || collections_delete.dig('status') != 'ok'
|
83
|
+
raise 'Failed to delete collection'
|
84
|
+
end
|
85
|
+
|
86
|
+
create_collection
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def create_collection
|
92
|
+
collections_get = @client.collections.get(collection_name: @config[:collection_name])
|
93
|
+
if !collections_get || collections_get.dig('status') != 'ok'
|
94
|
+
collections_create = @client.collections.create(
|
95
|
+
collection_name: @config[:collection_name],
|
96
|
+
vectors: {
|
97
|
+
distance: "Cosine",
|
98
|
+
size: 1536
|
99
|
+
}
|
100
|
+
)
|
101
|
+
if !collections_create || collections_create.dig('status') != 'ok'
|
102
|
+
raise 'Failed to create collection'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# create index for field "id" in collection
|
107
|
+
collections_create_index = @client.collections.create_index(collection_name: @config[:collection_name], field_name: 'id', field_schema: 'keyword')
|
108
|
+
if !collections_create_index || collections_create_index.dig('status') != 'ok'
|
109
|
+
raise 'Failed to create index for field "id" on collection'
|
110
|
+
end
|
111
|
+
|
112
|
+
true
|
113
|
+
end
|
101
114
|
end
|
102
115
|
end
|
data/lib/speaky/version.rb
CHANGED
data/lib/speaky.rb
CHANGED
@@ -71,6 +71,7 @@ module Speaky
|
|
71
71
|
#
|
72
72
|
# Example of usage:
|
73
73
|
# Speaky.ask("What is the capital of France?")
|
74
|
+
# Speaky.ask("What is the capital of France?", template: "You are an AI assistant. You are asked a question and you provide an answer. Use the provided context to generate the answer to the question. Context: {{context}} Question: {{question}}")
|
74
75
|
def ask(question, template: nil, **other_params)
|
75
76
|
# load template
|
76
77
|
default_template = <<~TEMPLATE
|
@@ -97,5 +98,29 @@ module Speaky
|
|
97
98
|
# ask the question
|
98
99
|
llm.chat(prompt)
|
99
100
|
end
|
101
|
+
|
102
|
+
# This is a method that re-embeds all Rails models into the vectorstore.
|
103
|
+
#
|
104
|
+
# Example of usage:
|
105
|
+
# Speaky.embed!
|
106
|
+
def embed!
|
107
|
+
# reset the vectorstore
|
108
|
+
vectorstore.reset
|
109
|
+
|
110
|
+
# re-embed all rails models that include the Concern module
|
111
|
+
Rails.application.eager_load!
|
112
|
+
rails_models = ActiveRecord::Base.descendants
|
113
|
+
rails_models.each do |rails_model|
|
114
|
+
next unless rails_model.instance_methods.include?(:save_for_speaky)
|
115
|
+
|
116
|
+
rails_model.find_in_batches do |batch|
|
117
|
+
batch.each do |record|
|
118
|
+
record.save_for_speaky
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
true
|
124
|
+
end
|
100
125
|
end
|
101
126
|
end
|