roseflow-pinecone 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|