activerecord-turbopuffer-adapter 0.1.6 → 0.1.7
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dbe88ca95c2999749426d72f89dd7d0327a53d5a08bf6a0b2446340d6b17e173
|
|
4
|
+
data.tar.gz: c6c1611fe66ea9ca7dff51fde19ce3843249d8b91e955aa21ba500d9fe8efe1a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4cd6c79fd3b22a79ca2d18a8ed68765360b7e63c9a3f2d4e3bb82d644553bbf7fcd93a05489f58c3285c5967ec3f2e2f522bafa7e4c1c9debf5190b4f626c85c
|
|
7
|
+
data.tar.gz: c8f7cdae01828498d93c66d345d34bdbf5cda39ff46ff13ec7126bfe97b42bba3d9c4b2337fbce08640755f87d49d42b9283cec227f9605d6b1af02bb9b1f998
|
data/README.md
CHANGED
|
@@ -56,6 +56,17 @@ class Document < ApplicationRecord
|
|
|
56
56
|
end
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
+
Alternatively, turbopuffer can generate embeddings for you. Declare `embed` on a string attribute and the vector is computed on write:
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
class Document < ApplicationRecord
|
|
63
|
+
turbopuffer_attribute "id", "uuid", not_null: 1
|
|
64
|
+
turbopuffer_attribute "body", "string", embed: "openai/text-embedding-3-small"
|
|
65
|
+
end
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
turbopuffer stores the vector in a computed `embed_body` attribute. `embed` also accepts a hash (`model:`, `attribute:`, `dims:`, `dtype:`) to name the vector attribute or set its size. Embedding is billed per token by model, see https://turbopuffer.com/docs/embedding for the supported models.
|
|
69
|
+
|
|
59
70
|
### Creating records
|
|
60
71
|
|
|
61
72
|
```ruby
|
|
@@ -104,6 +115,7 @@ Document.find("018f...")
|
|
|
104
115
|
|
|
105
116
|
Document.rank_by("vector", "ANN", query_vector).limit(10)
|
|
106
117
|
Document.rank_by("text", "BM25", "quick walrus").limit(10)
|
|
118
|
+
Document.rank_by("body", "ANN", ["Embed", "sea mammals"]).limit(10)
|
|
107
119
|
|
|
108
120
|
Document.consistency(:eventual).where(published: true)
|
|
109
121
|
|
|
@@ -151,7 +151,7 @@ module ActiveRecord
|
|
|
151
151
|
schema: model.turbopuffer_schema_hash
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
if model.turbopuffer_attributes.any?
|
|
154
|
+
if model.turbopuffer_attributes.any? { |attribute| attribute.ann || attribute.embed }
|
|
155
155
|
tpuf_insert_args[:distance_metric] = model.turbopuffer_distance_metric
|
|
156
156
|
end
|
|
157
157
|
|
|
@@ -5,16 +5,20 @@ module Turbopuffer
|
|
|
5
5
|
TYPES = %r{\A(?:\[\])?(?:string|uuid|int|uint|float|bool|datetime)\z|\Abytes\z|\A\[\d+\](?:f16|f32|i8)\z|\A\{\}f16\z}
|
|
6
6
|
VECTOR_TYPES = %r{\A\[\d+\]|\A\{\}}
|
|
7
7
|
|
|
8
|
-
attr_reader :name, :type, :filterable, :full_text_search, :ann, :glob, :regex, :notnull
|
|
8
|
+
attr_reader :name, :type, :filterable, :full_text_search, :ann, :glob, :regex, :embed, :notnull
|
|
9
9
|
|
|
10
10
|
def initialize(name, type, not_null: 0, filterable: false, full_text_search: false,
|
|
11
|
-
ann: false, glob: false, regex: false)
|
|
11
|
+
ann: false, glob: false, regex: false, embed: nil)
|
|
12
12
|
type = type.to_s
|
|
13
13
|
|
|
14
14
|
unless TYPES.match?(type)
|
|
15
15
|
raise ArgumentError, "unknown turbopuffer type #{type.inspect} for attribute #{name.inspect}"
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
if embed && type != "string"
|
|
19
|
+
raise ArgumentError, "embed is only supported on string attributes, #{name.inspect} is #{type.inspect}"
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
@name = name
|
|
19
23
|
@type = type
|
|
20
24
|
@filterable = filterable
|
|
@@ -22,6 +26,7 @@ module Turbopuffer
|
|
|
22
26
|
@ann = ann
|
|
23
27
|
@glob = glob
|
|
24
28
|
@regex = regex
|
|
29
|
+
@embed = embed
|
|
25
30
|
|
|
26
31
|
@notnull = not_null
|
|
27
32
|
end
|
|
@@ -48,10 +48,10 @@ module Turbopuffer
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
class_methods do
|
|
51
|
-
def turbopuffer_attribute(name, type, not_null: 0, filterable: false,
|
|
52
|
-
|
|
51
|
+
def turbopuffer_attribute(name, type, not_null: 0, filterable: false, full_text_search: false,
|
|
52
|
+
ann: false, glob: false, regex: false, embed: nil)
|
|
53
53
|
attribute = ::Turbopuffer::ActiveRecord::Schema::Attribute.new(
|
|
54
|
-
name.to_s, type, not_null:, filterable:, full_text_search:, ann:, glob:, regex:
|
|
54
|
+
name.to_s, type, not_null:, filterable:, full_text_search:, ann:, glob:, regex:, embed:
|
|
55
55
|
)
|
|
56
56
|
|
|
57
57
|
self.turbopuffer_attributes =
|
|
@@ -119,6 +119,7 @@ module Turbopuffer
|
|
|
119
119
|
attrs[:ann] = true if attribute.ann
|
|
120
120
|
attrs[:glob] = true if attribute.glob
|
|
121
121
|
attrs[:regex] = true if attribute.regex
|
|
122
|
+
attrs[:embed] = attribute.embed if attribute.embed
|
|
122
123
|
attrs[:sparse_knn] = { distance_metric: "dot_product" } if attribute.type == "{}f16"
|
|
123
124
|
|
|
124
125
|
schema[attribute.name] = attrs
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord-turbopuffer-adapter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Richard Monette
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-10-06 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: activerecord
|