chromable 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9df743def1991fb00b56fdfb0878642a2e5568136d4078dcb77084cf47c6ce14
4
- data.tar.gz: 6972ef16ef5c9f6f2f39de7e18c7028399d73b917001243c272e3b94d41839dc
3
+ metadata.gz: d44fa49957eefd26d00d3fb2315b51f928bd6ecdac7cdc4f849537cac23f036b
4
+ data.tar.gz: ab51d49d9b558e6d6ba936640026af66258567c0750f2ce11c7b6e01a0b8fea1
5
5
  SHA512:
6
- metadata.gz: 07adc75fffe609a6e493f30091745093c3bb9164cd8e64c1f81519f8c447c4a6142075de97d461062903c28ac4d1a15d79bc501c57731e0d167a8562a696650b
7
- data.tar.gz: 7818ee8d5a931f5e7936a0e27bb3bc716f349415e01f3cda33ff4cd72cf3ee237a5df157709a562238469659a828121e7d55b772b531bd06c1ddc2c7bc499204
6
+ metadata.gz: 2a6be5bd9ec59535eb33a59fc543baa23954ac43c4bc69b8a6e6d19eaab231d313180ba714781f85342f838bfdd4fd70fcfa32c785f663b880128d6a9425a69e
7
+ data.tar.gz: f63ffea813494e3143c16ed900e190d52866fa11348bac39db894c09ad885e66115b0cb8d0e492f2fb18846b29d8fcb76c4dbdbf3c271e3fd4f6afb417350ee9
data/.rubocop.yml CHANGED
@@ -2,7 +2,7 @@ require:
2
2
  - rubocop-rspec
3
3
 
4
4
  AllCops:
5
- TargetRubyVersion: 2.6
5
+ TargetRubyVersion: 3.0
6
6
  NewCops: enable
7
7
 
8
8
  Layout/LineLength:
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
- # Call OpenAI now please :)
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 current instance.
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
- All `chromable` method arguments are optional.
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Chromable
4
- VERSION = '0.1.5'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/chromable.rb CHANGED
@@ -4,19 +4,20 @@ require_relative 'chromable/version'
4
4
 
5
5
  # Ruby on Rails integration for ChromaDB.
6
6
  module Chromable
7
- def self.included(base)
7
+ def self.included(base)
8
8
  base.extend ClassMethods
9
9
  base.class_attribute :collection_name
10
10
  base.class_attribute :document
11
11
  base.class_attribute :metadata
12
12
  base.class_attribute :embedder
13
-
13
+
14
14
  base.after_save :chroma_upsert_embedding
15
15
  base.after_destroy :chroma_destroy_embedding
16
16
  end
17
17
 
18
+ # Methods to be added to the model class.
18
19
  module ClassMethods
19
- def chromable(collection_name: nil, document: nil, metadata: nil, embedder: nil)
20
+ def chromable(document:, metadata: nil, embedder: nil, collection_name: nil)
20
21
  self.collection_name = (collection_name.presence || name.underscore.pluralize)
21
22
  self.document = document
22
23
  self.metadata = metadata
@@ -27,7 +28,25 @@ module Chromable
27
28
  Chroma::Resources::Collection.get_or_create(collection_name)
28
29
  end
29
30
 
30
- alias_method :collection, :chroma_collection unless method_defined? :collection
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
31
50
  end
32
51
 
33
52
  def chroma_embedding
@@ -35,14 +54,7 @@ module Chromable
35
54
  end
36
55
 
37
56
  def chroma_upsert_embedding
38
- self.class.chroma_collection.upsert(
39
- Chroma::Resources::Embedding.new(
40
- id: id,
41
- document: self.class.document ? send(self.class.document) : nil,
42
- embedding: self.class.embedder ? send(self.class.embedder) : nil,
43
- metadata: self.class.metadata ? self.class.metadata.index_with { |attribute| send(attribute) } : nil
44
- )
45
- )
57
+ self.class.chroma_collection.upsert(build_embedding)
46
58
  end
47
59
 
48
60
  def chroma_destroy_embedding
@@ -52,4 +64,17 @@ module Chromable
52
64
  alias embedding chroma_embedding unless method_defined? :embedding
53
65
  alias upsert_embedding chroma_upsert_embedding unless method_defined? :upsert_embedding
54
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
55
80
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chromable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
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-09 00:00:00.000000000 Z
11
+ date: 2023-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chroma-db