roseflow-pinecone 0.1.0
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 +7 -0
- data/.rspec +3 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +7 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +21 -0
- data/README.md +47 -0
- data/Rakefile +10 -0
- data/config/pinecone.yml +3 -0
- data/lib/roseflow/pinecone/client.rb +102 -0
- data/lib/roseflow/pinecone/collection.rb +46 -0
- data/lib/roseflow/pinecone/config.rb +16 -0
- data/lib/roseflow/pinecone/index.rb +52 -0
- data/lib/roseflow/pinecone/object.rb +11 -0
- data/lib/roseflow/pinecone/response.rb +142 -0
- data/lib/roseflow/pinecone/structs.rb +44 -0
- data/lib/roseflow/pinecone/vector.rb +77 -0
- data/lib/roseflow/pinecone/vector_store.rb +48 -0
- data/lib/roseflow/pinecone/vectors/common.rb +36 -0
- data/lib/roseflow/pinecone/vectors/deletion.rb +38 -0
- data/lib/roseflow/pinecone/vectors/filter.rb +73 -0
- data/lib/roseflow/pinecone/vectors/query.rb +57 -0
- data/lib/roseflow/pinecone/vectors/sparse_vector.rb +40 -0
- data/lib/roseflow/pinecone/vectors/update.rb +40 -0
- data/lib/roseflow/pinecone/vectors/upsert.rb +42 -0
- data/lib/roseflow/pinecone/vectors/vector_object.rb +43 -0
- data/lib/roseflow/pinecone/version.rb +18 -0
- data/lib/roseflow/pinecone.rb +22 -0
- data/roseflow-pinecone.gemspec +48 -0
- data/sig/roseflow/pinecone.rbs +6 -0
- metadata +230 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Roseflow
|
4
|
+
module Pinecone
|
5
|
+
module Vectors
|
6
|
+
module Common
|
7
|
+
def self.extended(base_class)
|
8
|
+
base_class.extend ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.included(base_class)
|
12
|
+
base_class.extend ClassMethods
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def self.new(input)
|
17
|
+
validation = self.contract_object.new.call(input)
|
18
|
+
if validation.success?
|
19
|
+
super(input)
|
20
|
+
else
|
21
|
+
raise ArgumentError.new(validation.errors.to_h.inspect)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_json
|
27
|
+
to_h.map do |key, value|
|
28
|
+
[key.to_s.split("_").map.with_index do |word, index|
|
29
|
+
index == 0 ? word : word.capitalize
|
30
|
+
end.join.to_sym, value]
|
31
|
+
end.to_h.to_json
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-struct"
|
4
|
+
require "dry-validation"
|
5
|
+
|
6
|
+
require "roseflow/pinecone/object"
|
7
|
+
require "roseflow/pinecone/vectors/filter"
|
8
|
+
require "roseflow/pinecone/vectors/common"
|
9
|
+
|
10
|
+
module Types
|
11
|
+
include Dry.Types()
|
12
|
+
end
|
13
|
+
|
14
|
+
module Roseflow
|
15
|
+
module Pinecone
|
16
|
+
class Vector
|
17
|
+
class Deletion < PineconeObject
|
18
|
+
include Roseflow::Pinecone::Vectors::Common
|
19
|
+
|
20
|
+
class DeletionContract < Dry::Validation::Contract
|
21
|
+
params do
|
22
|
+
optional(:ids).filled(:array)
|
23
|
+
optional(:namespace).filled(:string)
|
24
|
+
optional(:filter).filled
|
25
|
+
optional(:delete_all).filled(:bool)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
contract_object DeletionContract
|
30
|
+
|
31
|
+
attribute? :ids, Dry::Types['array'].of(Dry::Types['string'])
|
32
|
+
attribute? :namespace, Dry::Types['string']
|
33
|
+
attribute? :filter, Types.Instance(Filter)
|
34
|
+
attribute? :delete_all, Dry::Types['bool'].default(false)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-struct"
|
4
|
+
require "dry-validation"
|
5
|
+
|
6
|
+
module Types
|
7
|
+
include Dry.Types()
|
8
|
+
|
9
|
+
StringOrNumberOrBoolean = Dry::Types['string'] | Dry::Types['integer'] | Dry::Types['float'] | Dry::Types['bool']
|
10
|
+
StringOrNumber = Dry::Types['string'] | Dry::Types['integer'] | Dry::Types['float']
|
11
|
+
Number = Dry::Types['integer'] | Dry::Types['float']
|
12
|
+
end
|
13
|
+
|
14
|
+
module Roseflow
|
15
|
+
module Pinecone
|
16
|
+
class Vector
|
17
|
+
class Filter < Hash
|
18
|
+
class FilterContract < Dry::Validation::Contract
|
19
|
+
schema do
|
20
|
+
optional(:$and).filled(:array)
|
21
|
+
optional(:$or).filled(:array)
|
22
|
+
optional(:$eq).filled(Types::StringOrNumberOrBoolean)
|
23
|
+
optional(:$ne).filled(Types::StringOrNumberOrBoolean)
|
24
|
+
optional(:$gt).filled(Types::Number)
|
25
|
+
optional(:$gte).filled(Types::Number)
|
26
|
+
optional(:$lt).filled(Types::Number)
|
27
|
+
optional(:$lte).filled(Types::Number)
|
28
|
+
optional(:$in).filled(:array).each(Types::StringOrNumber)
|
29
|
+
optional(:$nin).filled(:array).each(Types::StringOrNumber)
|
30
|
+
end
|
31
|
+
|
32
|
+
rule(:$and) do
|
33
|
+
if key?
|
34
|
+
key(:$and).failure("'$any' must be an array") unless value.is_a?(Array)
|
35
|
+
|
36
|
+
value.each do |v|
|
37
|
+
key(:$and).failure("'$any' must be an array of filters") unless v.is_a?(Filter) || to_filter(v).is_a?(Filter)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
rule(:$or) do
|
43
|
+
if key?
|
44
|
+
key(:$or).failure("'$or' must be an array") unless value.is_a?(Array)
|
45
|
+
|
46
|
+
value.each do |v|
|
47
|
+
key(:$or).failure("'$or' must be an array of filters") unless v.is_a?(Filter) || to_filter(v).is_a?(Filter)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_filter(input)
|
53
|
+
return false unless input.is_a?(Hash)
|
54
|
+
return Filter.new(input)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.new(input)
|
59
|
+
validation = FilterContract.new.call(input)
|
60
|
+
if validation.success?
|
61
|
+
super(input)
|
62
|
+
else
|
63
|
+
raise ArgumentError.new(validation.errors.to_h.inspect)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.default?
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-struct"
|
4
|
+
require "dry-validation"
|
5
|
+
|
6
|
+
require "roseflow/pinecone/vectors/filter"
|
7
|
+
require "roseflow/pinecone/vectors/sparse_vector"
|
8
|
+
|
9
|
+
module Types
|
10
|
+
include Dry.Types()
|
11
|
+
end
|
12
|
+
|
13
|
+
module Roseflow
|
14
|
+
module Pinecone
|
15
|
+
class Vector
|
16
|
+
class Query < PineconeObject
|
17
|
+
include Roseflow::Pinecone::Vectors::Common
|
18
|
+
|
19
|
+
class QueryContract < Dry::Validation::Contract
|
20
|
+
params do
|
21
|
+
optional(:vector).filled(:array)
|
22
|
+
optional(:id).filled(:string)
|
23
|
+
end
|
24
|
+
|
25
|
+
rule(:vector, :id) do
|
26
|
+
if !values[:vector].nil? && !values[:id].nil?
|
27
|
+
key(:vector).failure("Only one of vector or id can be specified")
|
28
|
+
key(:id).failure("Only one of vector or id can be specified")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
contract_object QueryContract
|
34
|
+
|
35
|
+
schema schema.strict
|
36
|
+
|
37
|
+
attribute :namespace, Dry::Types['string'].default("")
|
38
|
+
attribute :include_values, Dry::Types['bool'].default(false)
|
39
|
+
attribute :include_metadata, Dry::Types['bool'].default(true)
|
40
|
+
attribute :top_k, Dry::Types['integer'].default(10)
|
41
|
+
attribute? :vector, Dry::Types['array'].of(Dry::Types['float'] | Dry::Types['integer'])
|
42
|
+
attribute? :filter, Filter
|
43
|
+
attribute? :sparse_vector, SparseVector
|
44
|
+
attribute? :id, Dry::Types['string']
|
45
|
+
|
46
|
+
def self.new(input)
|
47
|
+
validation = self.contract_object.new.call(input)
|
48
|
+
if validation.success?
|
49
|
+
super(input)
|
50
|
+
else
|
51
|
+
raise ArgumentError.new(validation.errors.to_h.inspect)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-struct"
|
4
|
+
require "dry-validation"
|
5
|
+
|
6
|
+
require "roseflow/pinecone/object"
|
7
|
+
require "roseflow/pinecone/vectors/common"
|
8
|
+
|
9
|
+
module Types
|
10
|
+
include Dry.Types()
|
11
|
+
end
|
12
|
+
|
13
|
+
module Roseflow
|
14
|
+
module Pinecone
|
15
|
+
class Vector
|
16
|
+
class SparseVector < PineconeObject
|
17
|
+
include Roseflow::Pinecone::Vectors::Common
|
18
|
+
|
19
|
+
class SparseVectorContract < Dry::Validation::Contract
|
20
|
+
params do
|
21
|
+
required(:indices).filled(:array)
|
22
|
+
required(:values).filled(:array)
|
23
|
+
end
|
24
|
+
|
25
|
+
rule(:indices, :values) do
|
26
|
+
unless values[:indices].size === values[:values].size
|
27
|
+
key(:indices).failure("Indices and values must be the same size")
|
28
|
+
key(:values).failure("Indices and values must be the same size")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
contract_object SparseVectorContract
|
34
|
+
|
35
|
+
attribute :indices, Dry::Types['array'].of(Dry::Types['integer'])
|
36
|
+
attribute :values, Dry::Types['array'].of(Dry::Types['float'] | Dry::Types['integer'])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-struct"
|
4
|
+
require "dry-validation"
|
5
|
+
|
6
|
+
require "roseflow/pinecone/object"
|
7
|
+
require "roseflow/pinecone/vectors/sparse_vector"
|
8
|
+
require "roseflow/pinecone/vectors/common"
|
9
|
+
|
10
|
+
module Types
|
11
|
+
include Dry.Types()
|
12
|
+
end
|
13
|
+
|
14
|
+
module Roseflow
|
15
|
+
module Pinecone
|
16
|
+
class Vector
|
17
|
+
class Update < PineconeObject
|
18
|
+
include Roseflow::Pinecone::Vectors::Common
|
19
|
+
|
20
|
+
class UpdateContract < Dry::Validation::Contract
|
21
|
+
params do
|
22
|
+
required(:id).filled(:string)
|
23
|
+
optional(:namespace).filled(:string)
|
24
|
+
optional(:values).filled(:array)
|
25
|
+
optional(:sparse_values).filled
|
26
|
+
optional(:metadata).filled(:hash)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
contract_object UpdateContract
|
31
|
+
|
32
|
+
attribute :id, Dry::Types['string']
|
33
|
+
attribute? :namespace, Dry::Types['string'].optional
|
34
|
+
attribute? :values, Dry::Types['array'].of(Dry::Types['float']).optional
|
35
|
+
attribute? :sparse_values, SparseVector.optional
|
36
|
+
attribute? :metadata, Dry::Types['hash'].optional
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-struct"
|
4
|
+
|
5
|
+
require "roseflow/pinecone/object"
|
6
|
+
require "roseflow/pinecone/vectors/sparse_vector"
|
7
|
+
require "roseflow/pinecone/vectors/vector_object"
|
8
|
+
require "roseflow/pinecone/vectors/common"
|
9
|
+
|
10
|
+
module Types
|
11
|
+
include Dry.Types()
|
12
|
+
end
|
13
|
+
|
14
|
+
module Roseflow
|
15
|
+
module Pinecone
|
16
|
+
class Vector
|
17
|
+
class Upsert < PineconeObject
|
18
|
+
include Roseflow::Pinecone::Vectors::Common
|
19
|
+
|
20
|
+
class UpsertContract < Dry::Validation::Contract
|
21
|
+
params do
|
22
|
+
required(:vectors).filled(:array)
|
23
|
+
optional(:namespace).filled(:string)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
contract_object UpsertContract
|
28
|
+
|
29
|
+
attribute :vectors, Dry::Types['array'].of(VectorObject)
|
30
|
+
attribute? :namespace, Dry::Types['string'].optional
|
31
|
+
|
32
|
+
def self.from(data)
|
33
|
+
raise ArgumentError, "Data must be a valid upsert hash" unless data.is_a?(Hash) && data.keys.include?(:vectors)
|
34
|
+
new(
|
35
|
+
vectors: data[:vectors].map { |vector| VectorObject.new(id: vector[:id], values: vector[:values]) },
|
36
|
+
namespace: data[:namespace]
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-struct"
|
4
|
+
require "dry-validation"
|
5
|
+
|
6
|
+
require "roseflow/pinecone/object"
|
7
|
+
require "roseflow/pinecone/vectors/sparse_vector"
|
8
|
+
require "roseflow/pinecone/vectors/common"
|
9
|
+
|
10
|
+
module Types
|
11
|
+
include Dry.Types()
|
12
|
+
|
13
|
+
Number = Types::Coercible::Float
|
14
|
+
# SparseVector = Roseflow::Pinecone::Vector::SparseVector
|
15
|
+
end
|
16
|
+
|
17
|
+
module Roseflow
|
18
|
+
module Pinecone
|
19
|
+
class Vector
|
20
|
+
class VectorObject < PineconeObject
|
21
|
+
include Roseflow::Pinecone::Vectors::Common
|
22
|
+
transform_keys(&:to_sym)
|
23
|
+
|
24
|
+
class VectorObjectContract < Dry::Validation::Contract
|
25
|
+
params do
|
26
|
+
required(:id).filled(:string)
|
27
|
+
required(:values).filled(:array)
|
28
|
+
optional(:sparse_values).filled
|
29
|
+
optional(:metadata).filled(:hash)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
contract_object VectorObjectContract
|
34
|
+
|
35
|
+
attribute :id, Dry::Types['string']
|
36
|
+
attribute :values, Dry::Types['array'].of(Types::Number)
|
37
|
+
attribute? :score, Types::Number.optional
|
38
|
+
attribute? :sparse_values, SparseVector.optional
|
39
|
+
attribute? :metadata, Dry::Types['hash'].optional
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Roseflow
|
4
|
+
module Pinecone
|
5
|
+
def self.gem_version
|
6
|
+
Gem::Version.new VERSION::STRING
|
7
|
+
end
|
8
|
+
|
9
|
+
module VERSION
|
10
|
+
MAJOR = 0
|
11
|
+
MINOR = 1
|
12
|
+
PATCH = 0
|
13
|
+
PRE = nil
|
14
|
+
|
15
|
+
STRING = [MAJOR, MINOR, PATCH, PRE].compact.join(".")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "pinecone/version"
|
4
|
+
|
5
|
+
require "roseflow/pinecone/client"
|
6
|
+
require "roseflow/pinecone/collection"
|
7
|
+
require "roseflow/pinecone/config"
|
8
|
+
require "roseflow/pinecone/response"
|
9
|
+
|
10
|
+
require "dry-struct"
|
11
|
+
|
12
|
+
module Types
|
13
|
+
include Dry.Types()
|
14
|
+
end
|
15
|
+
|
16
|
+
module Roseflow
|
17
|
+
module Pinecone
|
18
|
+
class Error < StandardError; end
|
19
|
+
class IndexURLNotSetError < Error; end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/roseflow/pinecone/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "roseflow-pinecone"
|
7
|
+
spec.version = Roseflow::Pinecone.gem_version
|
8
|
+
spec.authors = ["Lauri Jutila"]
|
9
|
+
spec.email = ["git@laurijutila.com"]
|
10
|
+
|
11
|
+
spec.summary = "Roseflow meets Pinecone"
|
12
|
+
spec.description = "Pinecone vector database integration and support for Roseflow."
|
13
|
+
spec.homepage = "https://github.com/roseflow-ai/roseflow-pinecone"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 3.2.0"
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/roseflow-ai/roseflow-pinecone"
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/roseflow-ai/roseflow-pinecone/blob/master/CHANGELOG.md"
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(__dir__) do
|
24
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
25
|
+
(File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
# Uncomment to register a new dependency of your gem
|
33
|
+
spec.add_dependency "activesupport"
|
34
|
+
spec.add_dependency "anyway_config", "~> 2.0"
|
35
|
+
spec.add_dependency "dry-struct"
|
36
|
+
spec.add_dependency "dry-validation"
|
37
|
+
spec.add_dependency "faraday"
|
38
|
+
spec.add_dependency "faraday-retry"
|
39
|
+
|
40
|
+
spec.add_development_dependency "awesome_print"
|
41
|
+
spec.add_development_dependency "pry"
|
42
|
+
spec.add_development_dependency "roseflow"
|
43
|
+
spec.add_development_dependency "webmock"
|
44
|
+
spec.add_development_dependency "vcr"
|
45
|
+
|
46
|
+
# For more information and examples about making a new gem, check out our
|
47
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
48
|
+
end
|