chromable 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/README.md +27 -7
- data/chromable.gemspec +0 -1
- data/lib/chromable/version.rb +1 -1
- data/lib/chromable.rb +44 -22
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d44fa49957eefd26d00d3fb2315b51f928bd6ecdac7cdc4f849537cac23f036b
|
4
|
+
data.tar.gz: ab51d49d9b558e6d6ba936640026af66258567c0750f2ce11c7b6e01a0b8fea1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a6be5bd9ec59535eb33a59fc543baa23954ac43c4bc69b8a6e6d19eaab231d313180ba714781f85342f838bfdd4fd70fcfa32c785f663b880128d6a9425a69e
|
7
|
+
data.tar.gz: f63ffea813494e3143c16ed900e190d52866fa11348bac39db894c09ad885e66115b0cb8d0e492f2fb18846b29d8fcb76c4dbdbf3c271e3fd4f6afb417350ee9
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -32,8 +32,14 @@ class Post < ApplicationRecord
|
|
32
32
|
|
33
33
|
chromable document: :content, metadata: %i[author category], embedder: :embed
|
34
34
|
|
35
|
-
def embed
|
36
|
-
|
35
|
+
def self.embed(text, **options)
|
36
|
+
options[:is_query] ||= false
|
37
|
+
|
38
|
+
if options[:is_query]
|
39
|
+
# Call OpenAI API to embed `text` as a search query.
|
40
|
+
else
|
41
|
+
# Call OpenAI API to embed `text` as a post content.
|
42
|
+
end
|
37
43
|
end
|
38
44
|
end
|
39
45
|
```
|
@@ -41,22 +47,36 @@ end
|
|
41
47
|
Where:
|
42
48
|
- `document:` is a callable represents the text content you want to embed and store in ChromaDB.
|
43
49
|
- `metadata:` is the list of attributes to be passed to ChromaDB as metadata to be used to filter.
|
44
|
-
- `embedder:` is a callable returns the embedding representation for the
|
50
|
+
- `embedder:` is a callable defined in the model that returns the embedding representation for the given `text` and `options`.
|
45
51
|
|
46
52
|
Optionaly you can pass `collection_name:`. If not passed, the plural form of the model name will be used.
|
47
53
|
|
48
|
-
|
54
|
+
The only required option for `chromable` method is `document:`.
|
49
55
|
|
50
|
-
At this point, `chromable` will create, update, and destroy the ChromaDB embeddings for your objects based on Rails callbacks.
|
56
|
+
At this point, `chromable` will create, update, and destroy the ChromaDB embeddings for your objects based on Rails `after_save` and `after_destroy` callbacks.
|
57
|
+
|
58
|
+
To interact with the ChromaDB collection, `chromable` provides `Model.query` method to query the collection and `Model.collection` method to access the collection directly.
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
puts Post.collection.count # Gets the number of documents inside the collection. Should always match Post.count.
|
62
|
+
|
63
|
+
Post.query(
|
64
|
+
query: params[:query],
|
65
|
+
results: 20,
|
66
|
+
where: chroma_search_filters,
|
67
|
+
type: 'query' # `type` here will be passed to `Post.embed` as an option.
|
68
|
+
)
|
69
|
+
```
|
70
|
+
|
71
|
+
`Model.query` accepts the same arguments accepted by `chroma-db` gem `query` method. Extra arguments will be passed to the `embedder:`. Behind the scene, `Model.query` will embed the given `query:` text, then query the collection, and return the closest `results:` records.
|
51
72
|
|
52
|
-
To interact with the ChromaDB collection, `chromable` provides `Model.collection` method to retrieve the collection instance.
|
53
73
|
Also, `chromable` provides the following methods for each model instance:
|
54
74
|
|
55
75
|
- `embedding`: Retrieves the instance's ChromaDB embedding object.
|
56
76
|
- `upsert_embedding`: Creates or updates the instance's ChromaDB embedding object.
|
57
77
|
- `destroy_embedding`: Destroys the instance's ChromaDB embedding object.
|
58
78
|
|
59
|
-
All these methods (including `Model.collection`) are available with `chroma_` prefix, if you have similar methods defined in your model.
|
79
|
+
All these methods (including `Model.query` and `Model.collection`) are available with `chroma_` prefix, if you have similar methods defined in your model.
|
60
80
|
|
61
81
|
## Development
|
62
82
|
|
data/chromable.gemspec
CHANGED
@@ -32,7 +32,6 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
33
33
|
spec.require_paths = ['lib']
|
34
34
|
|
35
|
-
spec.add_dependency 'activesupport', '>= 6.1'
|
36
35
|
spec.add_dependency 'chroma-db', '>= 0.6.0'
|
37
36
|
|
38
37
|
# For more information and examples about making a new gem, check out our
|
data/lib/chromable/version.rb
CHANGED
data/lib/chromable.rb
CHANGED
@@ -1,25 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'active_support/concern'
|
4
|
-
|
5
3
|
require_relative 'chromable/version'
|
6
4
|
|
7
5
|
# Ruby on Rails integration for ChromaDB.
|
8
6
|
module Chromable
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
def self.included(base)
|
8
|
+
base.extend ClassMethods
|
9
|
+
base.class_attribute :collection_name
|
10
|
+
base.class_attribute :document
|
11
|
+
base.class_attribute :metadata
|
12
|
+
base.class_attribute :embedder
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
class_attribute :metadata
|
18
|
-
class_attribute :embedder
|
14
|
+
base.after_save :chroma_upsert_embedding
|
15
|
+
base.after_destroy :chroma_destroy_embedding
|
19
16
|
end
|
20
17
|
|
21
|
-
|
22
|
-
|
18
|
+
# Methods to be added to the model class.
|
19
|
+
module ClassMethods
|
20
|
+
def chromable(document:, metadata: nil, embedder: nil, collection_name: nil)
|
23
21
|
self.collection_name = (collection_name.presence || name.underscore.pluralize)
|
24
22
|
self.document = document
|
25
23
|
self.metadata = metadata
|
@@ -30,7 +28,25 @@ module Chromable
|
|
30
28
|
Chroma::Resources::Collection.get_or_create(collection_name)
|
31
29
|
end
|
32
30
|
|
33
|
-
|
31
|
+
def chroma_query( # rubocop:disable Metrics/ParameterLists
|
32
|
+
query:,
|
33
|
+
results: 10,
|
34
|
+
where: {},
|
35
|
+
where_document: {},
|
36
|
+
include: %w[metadatas documents distances],
|
37
|
+
**embedder_options
|
38
|
+
)
|
39
|
+
find(chroma_collection.query(
|
40
|
+
query_embeddings: [send(embedder, query, **embedder_options)],
|
41
|
+
results: results,
|
42
|
+
where: where,
|
43
|
+
where_document: where_document,
|
44
|
+
include: include
|
45
|
+
).map(&:id))
|
46
|
+
end
|
47
|
+
|
48
|
+
alias collection chroma_collection unless method_defined? :collection
|
49
|
+
alias query chroma_query unless method_defined? :query
|
34
50
|
end
|
35
51
|
|
36
52
|
def chroma_embedding
|
@@ -38,14 +54,7 @@ module Chromable
|
|
38
54
|
end
|
39
55
|
|
40
56
|
def chroma_upsert_embedding
|
41
|
-
self.class.chroma_collection.upsert(
|
42
|
-
Chroma::Resources::Embedding.new(
|
43
|
-
id: id,
|
44
|
-
document: self.class.document ? send(self.class.document) : nil,
|
45
|
-
embedding: self.class.embedder ? send(self.class.embedder) : nil,
|
46
|
-
metadata: self.class.metadata ? self.class.metadata.index_with { |attribute| send(attribute) } : nil
|
47
|
-
)
|
48
|
-
)
|
57
|
+
self.class.chroma_collection.upsert(build_embedding)
|
49
58
|
end
|
50
59
|
|
51
60
|
def chroma_destroy_embedding
|
@@ -55,4 +64,17 @@ module Chromable
|
|
55
64
|
alias embedding chroma_embedding unless method_defined? :embedding
|
56
65
|
alias upsert_embedding chroma_upsert_embedding unless method_defined? :upsert_embedding
|
57
66
|
alias destroy_embedding chroma_destroy_embedding unless method_defined? :destroy_embedding
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def build_embedding
|
71
|
+
document = send(self.class.document)
|
72
|
+
|
73
|
+
Chroma::Resources::Embedding.new(
|
74
|
+
id: id,
|
75
|
+
document: document,
|
76
|
+
embedding: self.class.embedder && self.class.send(self.class.embedder, document),
|
77
|
+
metadata: self.class.metadata&.index_with { |attribute| send(attribute) }
|
78
|
+
)
|
79
|
+
end
|
58
80
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chromable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ali Hamdi Ali Fadel
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-12-
|
11
|
+
date: 2023-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activesupport
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '6.1'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '6.1'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: chroma-db
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|