multiwoven-integrations 0.34.12 → 0.34.13

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: 9cab4c47cb2b8615acb9490ca83db71fe20c32d78c7a5f72820bb69d7ed2b51b
4
- data.tar.gz: 5273027c214e7610696f51b20bc9d5fa19f3a00aab0b78db444aba86fcf22d41
3
+ metadata.gz: d5a27bc8992444e43358eb0253d81aa23994d94c9381c5619ecfae56345abec4
4
+ data.tar.gz: f82de6bbef7d7e07b41a71f7f3511a679e50a0d1db8d68fecf435f5373751c35
5
5
  SHA512:
6
- metadata.gz: 1edaa71f204bcc4c98fdb6b9b26d698f6dfd8402ee2bdc404c613335b3fa2e7c8c56ce8eef1786b2ad4a0952d24fc420ffe423b7a7d8ba337eaae2fa44aa23a4
7
- data.tar.gz: 4573c6094113222d69ff96dda49567152a78ea54ae408c2653fc2cd309bee7059b85ccc577bd85d83dd459e8d56d0573ed9caf8ad20eb098f098bcff31fa7c2a
6
+ metadata.gz: a4ade2504dd16517a67f782d6268ce23baf0fa7875ab8744f0aa46b564b07c8dffb25d00457dcc650f215b402882077ee2b048d30cb82d465a15c5aac76a0865
7
+ data.tar.gz: e5fb112e74adb923a98b4b6c6e708345005371aa57881ef42a271217237513768bb0e63f91a37df6dbfe596c2a3a1c10cf73d9423e7355b3ac5720ba98ed4fd4
@@ -192,6 +192,7 @@ module Multiwoven
192
192
  attribute :source, Connector
193
193
  attribute :vector, Types::Array.of(Types::Float) | Types::String
194
194
  attribute :limit, Types::Integer.default(1)
195
+ attribute? :filters, Types::Array.of(Types::Hash).optional.default([])
195
196
  end
196
197
 
197
198
  class ControlMessage < ProtocolModel
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Multiwoven
4
4
  module Integrations
5
- VERSION = "0.34.12"
5
+ VERSION = "0.34.13"
6
6
 
7
7
  ENABLED_SOURCES = %w[
8
8
  Snowflake
@@ -34,11 +34,22 @@ module Multiwoven::Integrations::Source
34
34
  connection_config = connection_config.with_indifferent_access
35
35
  connection = create_connection(connection_config)
36
36
  pinecone_index = connection.index(@index_name)
37
- response = pinecone_index.query(vector: vector_search_config[:vector],
38
- namespace: @namespace,
39
- top_k: vector_search_config[:limit],
40
- include_values: true,
41
- include_metadata: true)
37
+
38
+ query_params = {
39
+ vector: vector_search_config[:vector],
40
+ top_k: vector_search_config[:limit],
41
+ include_values: true,
42
+ include_metadata: true
43
+ }
44
+
45
+ namespace = @namespace
46
+ query_params[:namespace] = namespace if namespace.present? && namespace != "__default__"
47
+
48
+ # Add filters if present
49
+ filters = vector_search_config[:filters] || []
50
+ query_params[:filter] = build_pinecone_filter(filters) if filters.present?
51
+
52
+ response = pinecone_index.query(**query_params)
42
53
  result = JSON.parse(response.body).with_indifferent_access
43
54
  records = result["matches"]
44
55
  records.map do |row|
@@ -68,6 +79,48 @@ module Multiwoven::Integrations::Source
68
79
  @index_name = connection_config["index_name"]
69
80
  @namespace = connection_config["namespace"]
70
81
  end
82
+
83
+ def build_pinecone_filter(filters)
84
+ return nil if filters.blank?
85
+
86
+ pinecone_filter = {}
87
+ filters.each do |filter|
88
+ process_filter(filter, pinecone_filter)
89
+ end
90
+
91
+ pinecone_filter.presence
92
+ end
93
+
94
+ def process_filter(filter, pinecone_filter)
95
+ field = filter[:field] || filter["field"]
96
+ operator = filter[:operator] || filter["operator"] || "eq"
97
+ value = filter[:value] || filter["value"]
98
+
99
+ return unless field.present? && value.present?
100
+
101
+ pinecone_filter[field] = build_pinecone_filter_value(operator, value)
102
+ end
103
+
104
+ def build_pinecone_filter_value(operator, value)
105
+ case operator.to_s
106
+ when "eq"
107
+ value
108
+ when "neq"
109
+ { "$ne" => value }
110
+ when "gt"
111
+ { "$gt" => value }
112
+ when "gte"
113
+ { "$gte" => value }
114
+ when "lt"
115
+ { "$lt" => value }
116
+ when "lte"
117
+ { "$lte" => value }
118
+ when "in"
119
+ { "$in" => value.is_a?(Array) ? value : [value] }
120
+ else
121
+ value
122
+ end
123
+ end
71
124
  end
72
125
  end
73
126
  end
@@ -47,6 +47,10 @@ module Multiwoven::Integrations::Source
47
47
  top: vector_search_config[:limit]
48
48
  }
49
49
 
50
+ # Add filters if present
51
+ filters = vector_search_config[:filters] || vector_search_config.filters || []
52
+ body[:filter] = build_qdrant_filter(filters) if filters.present?
53
+
50
54
  response = Multiwoven::Integrations::Core::HttpClient.request(
51
55
  url,
52
56
  HTTP_POST,
@@ -81,6 +85,72 @@ module Multiwoven::Integrations::Source
81
85
  def build_url(url)
82
86
  format(url, host: @host, collection_name: @collection_name)
83
87
  end
88
+
89
+ def build_qdrant_filter(filters)
90
+ return nil if filters.blank?
91
+
92
+ must_conditions = []
93
+ must_not_conditions = []
94
+
95
+ filters.each do |filter|
96
+ process_qdrant_filter(filter, must_conditions, must_not_conditions)
97
+ end
98
+
99
+ build_qdrant_filter_hash(must_conditions, must_not_conditions)
100
+ end
101
+
102
+ def process_qdrant_filter(filter, must_conditions, must_not_conditions)
103
+ field, operator, value = extract_filter_fields(filter)
104
+ return unless field.present? && value.present?
105
+
106
+ condition = build_qdrant_condition(field, operator, value)
107
+ return unless condition
108
+
109
+ add_condition_to_array(condition, operator, must_conditions, must_not_conditions)
110
+ end
111
+
112
+ def extract_filter_fields(filter)
113
+ [
114
+ filter[:field] || filter["field"],
115
+ filter[:operator] || filter["operator"] || "eq",
116
+ filter[:value] || filter["value"]
117
+ ]
118
+ end
119
+
120
+ def add_condition_to_array(condition, operator, must_conditions, must_not_conditions)
121
+ if operator.to_s == "neq"
122
+ must_not_conditions << condition
123
+ else
124
+ must_conditions << condition
125
+ end
126
+ end
127
+
128
+ def build_qdrant_condition(field, operator, value)
129
+ case operator.to_s
130
+ when "eq"
131
+ { key: field, match: { value: value } }
132
+ when "neq"
133
+ { key: field, match: { value: value } }
134
+ when "gt"
135
+ { key: field, range: { gt: value } }
136
+ when "gte"
137
+ { key: field, range: { gte: value } }
138
+ when "lt"
139
+ { key: field, range: { lt: value } }
140
+ when "lte"
141
+ { key: field, range: { lte: value } }
142
+ when "in"
143
+ { key: field, match: { any: value.is_a?(Array) ? value : [value] } }
144
+ end
145
+ end
146
+
147
+ def build_qdrant_filter_hash(must_conditions, must_not_conditions)
148
+ qdrant_filter = {}
149
+ qdrant_filter[:must] = must_conditions if must_conditions.present?
150
+ qdrant_filter[:must_not] = must_not_conditions if must_not_conditions.present?
151
+
152
+ qdrant_filter.presence
153
+ end
84
154
  end
85
155
  end
86
156
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multiwoven-integrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.34.12
4
+ version: 0.34.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Subin T P
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-11-24 00:00:00.000000000 Z
11
+ date: 2025-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport