bx_builder_chain 0.1.8 → 0.1.9

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: b7694b1cbe868aa9aa9ca318e27393cbf42cd640b9ebb19cb64f79866cdfd916
4
- data.tar.gz: b72ff57d3e402c6da8d20bce56510a9aaf5183b62f558fd30862e384273be861
3
+ metadata.gz: 4aa72e8ded8be5ea40f3cb865f989eabe6f6c8acee8fd51b2602e4e61b866c2a
4
+ data.tar.gz: 0d9ddd1c44ce88ea1fbf3f0970f1e9735116ecded0546a3ad5467ec062312463
5
5
  SHA512:
6
- metadata.gz: 07f4da8f3ed4110434ad99eb60bfa49db4ddc19f5ebc5fd8780a986cf6943d11404db29ac9500e39e97c19ef179ebcb234e915629c3d164f652c5fa05abb51c0
7
- data.tar.gz: 39c074e3f2cabc584d9bb02f77eae892132e33675e8ae0043a4501653b90ac6eab31b469210406b39e1568db6f5c75f1e755f26b0436a99314a270cb0f686fa9
6
+ metadata.gz: d774555dbd4e0d775c2e0b3e23384a1f20231ee8c118c62c16c7867f2e9d9cebab24ac48512896c9f61a9d2e09cc21941b5b4fcb963eb1f3f891f4fe6a0d9017
7
+ data.tar.gz: 1570c0677f6b47686b76437daf4ccf8652e0659ffce821ebc68f3857e251db055b02acc3b0a13d9b63a7d79f9d11535934c0d483209e50680e4711894a7dddc1
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Paul Ketelle"]
9
9
  spec.email = ["paul.ketelle@builder.ai"]
10
10
 
11
- spec.summary = "Write a short summary, because RubyGems requires one."
12
- spec.description = "Write a longer description or delete this line."
11
+ spec.summary = "LangChain but for the builder tech stack."
12
+ spec.description = "LangChain but for the builder tech stack."
13
13
  spec.license = "MIT"
14
14
  spec.required_ruby_version = ">= 2.6.0"
15
15
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BxBuilderChain
4
- VERSION = "0.1.8"
4
+ VERSION = "0.1.9"
5
5
  end
@@ -9,6 +9,7 @@ Dotenv.load
9
9
  loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
10
10
  loader.ignore("#{__dir__}/bx_builder_chain.rb")
11
11
  loader.ignore("#{__dir__}/bx_builder_chain/configuration.rb")
12
+ loader.ignore("#{__dir__}/generators")
12
13
  loader.setup
13
14
 
14
15
  module BxBuilderChain
@@ -1,10 +1,9 @@
1
1
  require 'rails/generators'
2
2
  require 'rails/generators/active_record'
3
3
 
4
- module Generators
5
4
  module BxBuilderChain
6
5
  class InstallGenerator < Rails::Generators::Base
7
- source_root File.expand_path('templates', __dir__)
6
+ source_root File.expand_path('../../../templates', __dir__)
8
7
 
9
8
  desc "Creates BxBuilderChain initializer, migration, and copies app templates for your application"
10
9
 
@@ -39,4 +38,3 @@ module Generators
39
38
  end
40
39
  end
41
40
  end
42
- end
data/lib/pgvector/pg.rb CHANGED
@@ -6,5 +6,23 @@ module Pgvector
6
6
  registry.register_type(0, "vector", nil, TextDecoder::Vector)
7
7
  registry.register_type(1, "vector", nil, BinaryDecoder::Vector)
8
8
  end
9
+
10
+ module BinaryDecoder
11
+ class Vector < ::PG::SimpleDecoder
12
+ def decode(string, tuple = nil, field = nil)
13
+ dim, unused = string[0, 4].unpack("nn")
14
+ raise "expected unused to be 0" if unused != 0
15
+ string[4..-1].unpack("g#{dim}")
16
+ end
17
+ end
18
+ end
19
+
20
+ module TextDecoder
21
+ class Vector < ::PG::SimpleDecoder
22
+ def decode(string, tuple = nil, field = nil)
23
+ Pgvector.decode(string)
24
+ end
25
+ end
26
+ end
9
27
  end
10
- end
28
+ end
data/lib/pgvector.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  module Pgvector
2
- autoload :PG, "pgvector/pg"
3
2
 
4
3
  def self.encode(data)
5
4
  "[#{data.to_a.map(&:to_f).join(",")}]"
@@ -1,3 +1,4 @@
1
+ require 'sequel'
1
2
  module Sequel
2
3
  module Plugins
3
4
  module Pgvector
@@ -7,6 +8,75 @@ module Sequel
7
8
  model.vector_columns[column.to_sym] = {}
8
9
  end
9
10
  end
11
+
12
+ module DatasetMethods
13
+ def nearest_neighbors(column, value, distance:)
14
+ value = ::Pgvector.encode(value) unless value.is_a?(String)
15
+ quoted_column = quote_identifier(column)
16
+ distance = distance.to_s
17
+
18
+ operator =
19
+ case distance
20
+ when "inner_product"
21
+ "<#>"
22
+ when "cosine"
23
+ "<=>"
24
+ when "euclidean"
25
+ "<->"
26
+ end
27
+
28
+ raise ArgumentError, "Invalid distance: #{distance}" unless operator
29
+
30
+ order = "#{quoted_column} #{operator} ?"
31
+
32
+ neighbor_distance =
33
+ if distance == "inner_product"
34
+ "(#{order}) * -1"
35
+ else
36
+ order
37
+ end
38
+
39
+ select_append(Sequel.lit("#{neighbor_distance} AS neighbor_distance", value))
40
+ .exclude(column => nil)
41
+ .order(Sequel.lit(order, value))
42
+ end
43
+ end
44
+
45
+ module ClassMethods
46
+ attr_accessor :vector_columns
47
+
48
+ Sequel::Plugins.def_dataset_methods(self, :nearest_neighbors)
49
+
50
+ Plugins.inherited_instance_variables(self, :@vector_columns => :dup)
51
+ end
52
+
53
+ module InstanceMethods
54
+ def nearest_neighbors(column, **options)
55
+ column = column.to_sym
56
+ # important! check if neighbor attribute before calling send
57
+ raise ArgumentError, "Invalid column" unless self.class.vector_columns[column]
58
+
59
+ self.class
60
+ .nearest_neighbors(column, self[column], **options)
61
+ .exclude(primary_key => self[primary_key])
62
+ end
63
+
64
+ def []=(k, v)
65
+ if self.class.vector_columns.key?(k.to_sym) && !v.is_a?(String)
66
+ super(k, ::Pgvector.encode(v))
67
+ else
68
+ super
69
+ end
70
+ end
71
+
72
+ def [](k)
73
+ if self.class.vector_columns.key?(k.to_sym)
74
+ ::Pgvector.decode(super)
75
+ else
76
+ super
77
+ end
78
+ end
79
+ end
10
80
  end
11
81
  end
12
- end
82
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bx_builder_chain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Ketelle
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-27 00:00:00.000000000 Z
11
+ date: 2023-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -150,7 +150,7 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: 2.8.3
153
- description: Write a longer description or delete this line.
153
+ description: LangChain but for the builder tech stack.
154
154
  email:
155
155
  - paul.ketelle@builder.ai
156
156
  executables: []
@@ -206,11 +206,7 @@ files:
206
206
  - lib/generators/bx_builder_chain/templates/migration.rb
207
207
  - lib/pgvector.rb
208
208
  - lib/pgvector/pg.rb
209
- - lib/pgvector/pg/binary_decoder/vector.rb
210
- - lib/pgvector/pg/text_decoder/vector.rb
211
209
  - lib/sequel/plugins/pgvector.rb
212
- - lib/sequel/plugins/pgvector/class_methods.rb
213
- - lib/sequel/plugins/pgvector/instance_methods.rb
214
210
  - sig/bx_langchain_chat.rbs
215
211
  homepage:
216
212
  licenses:
@@ -234,5 +230,5 @@ requirements: []
234
230
  rubygems_version: 3.1.0
235
231
  signing_key:
236
232
  specification_version: 4
237
- summary: Write a short summary, because RubyGems requires one.
233
+ summary: LangChain but for the builder tech stack.
238
234
  test_files: []
@@ -1,14 +0,0 @@
1
- module Pgvector
2
- module PG
3
- module BinaryDecoder
4
- class Vector < ::PG::SimpleDecoder
5
- def decode(string, tuple = nil, field = nil)
6
- dim, unused = string[0, 4].unpack("nn")
7
- raise "expected unused to be 0" if unused != 0
8
- string[4..-1].unpack("g#{dim}")
9
- end
10
- end
11
- end
12
- end
13
- end
14
-
@@ -1,12 +0,0 @@
1
- module Pgvector
2
- module PG
3
- module TextDecoder
4
- class Vector < ::PG::SimpleDecoder
5
- def decode(string, tuple = nil, field = nil)
6
- Pgvector.decode(string)
7
- end
8
- end
9
- end
10
- end
11
- end
12
-
@@ -1,47 +0,0 @@
1
- module Sequel
2
- module Plugins
3
- module Pgvector
4
- module ClassMethods
5
- attr_accessor :vector_columns
6
-
7
- def nearest_neighbors(column, value, distance:, threshold: nil)
8
- value = ::Pgvector.encode(value) unless value.is_a?(String)
9
- quoted_column = dataset.quote_identifier(column)
10
- distance = distance.to_s
11
-
12
- operator =
13
- case distance
14
- when "inner_product"
15
- "<#>"
16
- when "cosine"
17
- "<=>"
18
- when "euclidean"
19
- "<->"
20
- else
21
- raise ArgumentError, "Invalid distance: #{distance}"
22
- end
23
-
24
- order = "#{quoted_column} #{operator} ?"
25
-
26
- neighbor_distance =
27
- if distance == "inner_product"
28
- "(#{order}) * -1"
29
- else
30
- order
31
- end
32
-
33
- query = select_append(Sequel.lit("#{neighbor_distance} AS neighbor_distance", value))
34
- .exclude(column => nil)
35
- .order(Sequel.lit(order, value))
36
-
37
- # Apply the WHERE condition only if threshold is provided
38
- query = query.where(Sequel.lit("(#{neighbor_distance}) < ?", value, threshold)) if threshold
39
-
40
- query
41
- end
42
-
43
- Plugins.inherited_instance_variables(self, :@vector_columns => :dup)
44
- end
45
- end
46
- end
47
- end
@@ -1,34 +0,0 @@
1
- module Sequel
2
- module Plugins
3
- module Pgvector
4
- module InstanceMethods
5
- def nearest_neighbors(column, **options)
6
- column = column.to_sym
7
- # important! check if neighbor attribute before calling send
8
- raise ArgumentError, "Invalid column" unless self.class.vector_columns[column]
9
-
10
- self.class
11
- .nearest_neighbors(column, self[column], **options)
12
- .exclude(primary_key => self[primary_key])
13
- end
14
-
15
- def []=(k, v)
16
- if self.class.vector_columns.key?(k.to_sym) && !v.is_a?(String)
17
- super(k, ::Pgvector.encode(v))
18
- else
19
- super
20
- end
21
- end
22
-
23
- def [](k)
24
- if self.class.vector_columns.key?(k.to_sym)
25
- ::Pgvector.decode(super)
26
- else
27
- super
28
- end
29
- end
30
- end
31
- end
32
- end
33
- end
34
-