vectra-client 1.0.8 → 1.1.1
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 +4 -4
- data/CHANGELOG.md +37 -0
- data/README.md +75 -0
- data/docs/_layouts/home.html +1 -1
- data/docs/_layouts/page.html +7 -0
- data/docs/api/cheatsheet.md +17 -0
- data/docs/api/methods.md +45 -0
- data/docs/api/overview.md +6 -0
- data/docs/guides/middleware.md +324 -0
- data/docs/guides/roadmap.md +53 -0
- data/examples/middleware_demo.rb +103 -0
- data/lib/vectra/client.rb +132 -15
- data/lib/vectra/health_check.rb +4 -2
- data/lib/vectra/middleware/base.rb +97 -0
- data/lib/vectra/middleware/cost_tracker.rb +121 -0
- data/lib/vectra/middleware/instrumentation.rb +44 -0
- data/lib/vectra/middleware/logging.rb +62 -0
- data/lib/vectra/middleware/pii_redaction.rb +65 -0
- data/lib/vectra/middleware/request.rb +62 -0
- data/lib/vectra/middleware/response.rb +65 -0
- data/lib/vectra/middleware/retry.rb +103 -0
- data/lib/vectra/middleware/stack.rb +74 -0
- data/lib/vectra/providers/memory.rb +56 -0
- data/lib/vectra/providers/pgvector.rb +50 -0
- data/lib/vectra/providers/qdrant.rb +39 -0
- data/lib/vectra/providers/weaviate.rb +64 -0
- data/lib/vectra/version.rb +1 -1
- data/lib/vectra.rb +9 -0
- metadata +13 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f1fd06b5874c1bc1da1244fb05321cda4a4759e234d9175159c5a6ba7ed8d40
|
|
4
|
+
data.tar.gz: 9d69e983f4ef5ed4d6bdd58e7a003e06045f3570ba1b3329587f82bcf07902a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7c1911470f96d83470dd98cdc6bb3e6c438a11e71b7317265388d22ae4c3792cea3e595661c927a42587b6008fc891940d511815932b3da478bfeb056ccf8c30
|
|
7
|
+
data.tar.gz: a3a17643736f8b9a19b92c81a87ce8749a4e55798085e474ef1bc2f13ab9f8c688b2bc7537467a851e59a31cf06390444a064a9d525cff8efb175dbae1de7c7c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v1.1.0](https://github.com/stokry/vectra/tree/v1.1.0) (2026-01-15)
|
|
4
|
+
|
|
5
|
+
[Full Changelog](https://github.com/stokry/vectra/compare/v1.0.8...v1.1.0)
|
|
6
|
+
|
|
7
|
+
### 🎉 Major Feature: Middleware System
|
|
8
|
+
|
|
9
|
+
This release introduces a **Rack-style middleware system** for all vector database operations.
|
|
10
|
+
|
|
11
|
+
#### Added
|
|
12
|
+
|
|
13
|
+
- **Middleware Stack** - All client operations now route through a composable middleware pipeline
|
|
14
|
+
- **5 Built-in Middleware**:
|
|
15
|
+
- `Vectra::Middleware::Logging` - Structured logs with timing for all operations
|
|
16
|
+
- `Vectra::Middleware::Retry` - Automatic retry with exponential/linear backoff for transient errors
|
|
17
|
+
- `Vectra::Middleware::Instrumentation` - Hooks for metrics and APM integration
|
|
18
|
+
- `Vectra::Middleware::PIIRedaction` - Automatic PII redaction (email, phone, SSN, credit cards)
|
|
19
|
+
- `Vectra::Middleware::CostTracker` - Track API costs per operation with callbacks
|
|
20
|
+
- **Request/Response Objects** - Type-safe objects with metadata attachment
|
|
21
|
+
- **Extensible Framework** - Create custom middleware by extending `Vectra::Middleware::Base`
|
|
22
|
+
- **Global & Per-Client Middleware** - Apply middleware globally (`Client.use`) or per-instance (`new(middleware: [...])`)
|
|
23
|
+
|
|
24
|
+
#### Changed
|
|
25
|
+
|
|
26
|
+
- All client operations (`upsert`, `query`, `fetch`, `update`, `delete`, `stats`, `list_indexes`, etc.) now route through middleware stack for consistency
|
|
27
|
+
- Middleware has complete visibility into all client operations
|
|
28
|
+
|
|
29
|
+
#### Documentation
|
|
30
|
+
|
|
31
|
+
- Added comprehensive middleware section to README
|
|
32
|
+
- Created `examples/middleware_demo.rb` demonstrating all 5 built-in middleware
|
|
33
|
+
- Full YARD documentation for all middleware classes
|
|
34
|
+
- Published [middleware guide](https://dev.to/stokry/rack-style-middleware-for-vector-databases-in-ruby-vectra-client-110-2jh3) on Dev.to
|
|
35
|
+
|
|
36
|
+
#### Migration Notes
|
|
37
|
+
|
|
38
|
+
No breaking changes. Middleware is opt-in - existing code works without modification.
|
|
39
|
+
|
|
3
40
|
## [v1.0.8](https://github.com/stokry/vectra/tree/v1.0.8) (2026-01-14)
|
|
4
41
|
|
|
5
42
|
[Full Changelog](https://github.com/stokry/vectra/compare/v1.0.7...v1.0.8)
|
data/README.md
CHANGED
|
@@ -109,6 +109,14 @@ results = client.hybrid_search(
|
|
|
109
109
|
text: 'ruby programming',
|
|
110
110
|
alpha: 0.7 # 70% semantic, 30% keyword
|
|
111
111
|
)
|
|
112
|
+
|
|
113
|
+
# Text-only search (keyword search without embeddings)
|
|
114
|
+
# Supported by: Qdrant, Weaviate, pgvector
|
|
115
|
+
results = client.text_search(
|
|
116
|
+
index: 'products',
|
|
117
|
+
text: 'iPhone 15 Pro',
|
|
118
|
+
top_k: 10
|
|
119
|
+
)
|
|
112
120
|
```
|
|
113
121
|
|
|
114
122
|
## Provider Examples
|
|
@@ -242,6 +250,59 @@ Real-world patterns for common use cases:
|
|
|
242
250
|
|
|
243
251
|
👉 **[Browse all Recipes & Patterns](https://vectra-docs.netlify.app/guides/recipes/)**
|
|
244
252
|
|
|
253
|
+
## Middleware System
|
|
254
|
+
|
|
255
|
+
Vectra features a powerful **Rack-style middleware system** that allows you to extend functionality without modifying core code.
|
|
256
|
+
|
|
257
|
+
### Quick Start
|
|
258
|
+
|
|
259
|
+
```ruby
|
|
260
|
+
# Global middleware (applies to all clients)
|
|
261
|
+
Vectra::Client.use Vectra::Middleware::Logging
|
|
262
|
+
Vectra::Client.use Vectra::Middleware::Retry, max_attempts: 5
|
|
263
|
+
Vectra::Client.use Vectra::Middleware::CostTracker
|
|
264
|
+
|
|
265
|
+
# Per-client middleware
|
|
266
|
+
client = Vectra::Client.new(
|
|
267
|
+
provider: :qdrant,
|
|
268
|
+
middleware: [
|
|
269
|
+
Vectra::Middleware::PIIRedaction,
|
|
270
|
+
Vectra::Middleware::Instrumentation
|
|
271
|
+
]
|
|
272
|
+
)
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Built-in Middleware
|
|
276
|
+
|
|
277
|
+
- **Logging** - Request/response logging with timing
|
|
278
|
+
- **Retry** - Automatic retries with exponential backoff
|
|
279
|
+
- **Instrumentation** - Metrics and monitoring integration
|
|
280
|
+
- **PIIRedaction** - Automatic PII (email, phone, SSN) redaction
|
|
281
|
+
- **CostTracker** - Track API usage costs per operation
|
|
282
|
+
|
|
283
|
+
### Custom Middleware
|
|
284
|
+
|
|
285
|
+
```ruby
|
|
286
|
+
class MyAuditMiddleware < Vectra::Middleware::Base
|
|
287
|
+
def before(request)
|
|
288
|
+
# Called before the operation
|
|
289
|
+
AuditLog.create!(action: request.operation, user: Current.user)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def after(request, response)
|
|
293
|
+
# Called after successful operation
|
|
294
|
+
puts "Duration: #{response.metadata[:duration_ms]}ms"
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def on_error(request, error)
|
|
298
|
+
# Called when an error occurs
|
|
299
|
+
ErrorTracker.notify(error, context: { operation: request.operation })
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
Vectra::Client.use MyAuditMiddleware
|
|
304
|
+
```
|
|
305
|
+
|
|
245
306
|
## Production Patterns
|
|
246
307
|
|
|
247
308
|
Vectra includes 7 production-ready patterns out of the box:
|
|
@@ -254,6 +315,20 @@ Vectra includes 7 production-ready patterns out of the box:
|
|
|
254
315
|
- **Health Checks** - `healthy?`, `ping`, and `health_check` methods
|
|
255
316
|
- **Instrumentation** - Datadog, New Relic, Sentry, Honeybadger support
|
|
256
317
|
|
|
318
|
+
## Roadmap
|
|
319
|
+
|
|
320
|
+
High-level roadmap for `vectra-client`:
|
|
321
|
+
|
|
322
|
+
- **1.x (near term)**
|
|
323
|
+
- Reranking middleware built on top of the existing Rack-style middleware stack.
|
|
324
|
+
- Additional middleware building blocks (sampling, tracing, score normalization).
|
|
325
|
+
- Smoother Rails UX for multi-tenant setups and larger demos (e‑commerce, RAG, recommendations).
|
|
326
|
+
- **Mid term**
|
|
327
|
+
- Additional providers where it makes sense and stays maintainable.
|
|
328
|
+
- Deeper documentation and recipes around reranking and hybrid search.
|
|
329
|
+
|
|
330
|
+
For a more detailed, always-up-to-date version, see the online roadmap: https://vectra-docs.netlify.app/guides/roadmap/
|
|
331
|
+
|
|
257
332
|
## Development
|
|
258
333
|
|
|
259
334
|
```bash
|
data/docs/_layouts/home.html
CHANGED
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
<!-- Hero Section -->
|
|
56
56
|
<section class="tma-hero">
|
|
57
57
|
<div class="tma-hero__container">
|
|
58
|
-
<span class="tma-hero__badge">v1.0
|
|
58
|
+
<span class="tma-hero__badge">v1.1.0 — Hybrid Search, Rails Generator & Middleware</span>
|
|
59
59
|
<h1 class="tma-hero__title">
|
|
60
60
|
Vector Databases,<br>
|
|
61
61
|
<span class="tma-hero__title-gradient">Unified for Ruby.</span>
|
data/docs/_layouts/page.html
CHANGED
|
@@ -91,6 +91,13 @@
|
|
|
91
91
|
<li><a href="https://github.com/stokry/vectra/issues" class="tma-sidebar__link" target="_blank">Report Issue ↗</a></li>
|
|
92
92
|
</ul>
|
|
93
93
|
</div>
|
|
94
|
+
|
|
95
|
+
<div class="tma-sidebar__section">
|
|
96
|
+
<h3 class="tma-sidebar__title">Resources</h3>
|
|
97
|
+
<ul class="tma-sidebar__list">
|
|
98
|
+
<li><a href="{{ site.baseurl }}/guides/roadmap" class="tma-sidebar__link {% if page.url == '/guides/roadmap/' %}tma-sidebar__link--active{% endif %}">Roadmap</a></li>
|
|
99
|
+
</ul>
|
|
100
|
+
</div>
|
|
94
101
|
</aside>
|
|
95
102
|
|
|
96
103
|
<!-- Main Content -->
|
data/docs/api/cheatsheet.md
CHANGED
|
@@ -98,6 +98,23 @@ results = client.hybrid_search(
|
|
|
98
98
|
|
|
99
99
|
Supported providers: Qdrant ✅, Weaviate ✅, pgvector ✅, Pinecone ⚠️
|
|
100
100
|
|
|
101
|
+
### Text Search (keyword-only, no embeddings)
|
|
102
|
+
|
|
103
|
+
```ruby
|
|
104
|
+
results = client.text_search(
|
|
105
|
+
index: 'products',
|
|
106
|
+
text: 'iPhone 15 Pro',
|
|
107
|
+
top_k: 10,
|
|
108
|
+
filter: { category: 'electronics' }
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
results.each do |match|
|
|
112
|
+
puts "#{match.id} (score=#{match.score.round(3)}): #{match.metadata['title']}"
|
|
113
|
+
end
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Supported providers: Qdrant ✅ (BM25), Weaviate ✅ (BM25), pgvector ✅ (PostgreSQL full-text)
|
|
117
|
+
|
|
101
118
|
### Fetch
|
|
102
119
|
|
|
103
120
|
```ruby
|
data/docs/api/methods.md
CHANGED
|
@@ -147,6 +147,51 @@ results = client.hybrid_search(
|
|
|
147
147
|
|
|
148
148
|
---
|
|
149
149
|
|
|
150
|
+
### `client.text_search(index:, text:, top_k: 10, namespace: nil, filter: nil, include_values: false, include_metadata: true)`
|
|
151
|
+
|
|
152
|
+
Text-only search (keyword search without requiring embeddings).
|
|
153
|
+
|
|
154
|
+
**Parameters:**
|
|
155
|
+
- `index` (String) - Index/collection name (uses client's default index when omitted)
|
|
156
|
+
- `text` (String) - Text query for keyword search
|
|
157
|
+
- `top_k` (Integer) - Number of results (default: 10)
|
|
158
|
+
- `namespace` (String, optional) - Namespace
|
|
159
|
+
- `filter` (Hash, optional) - Metadata filter
|
|
160
|
+
- `include_values` (Boolean) - Include vector values (default: false)
|
|
161
|
+
- `include_metadata` (Boolean) - Include metadata (default: true)
|
|
162
|
+
|
|
163
|
+
**Returns:** `Vectra::QueryResult`
|
|
164
|
+
|
|
165
|
+
**Provider Support:**
|
|
166
|
+
- ✅ Qdrant (BM25)
|
|
167
|
+
- ✅ Weaviate (BM25)
|
|
168
|
+
- ✅ pgvector (PostgreSQL full-text search)
|
|
169
|
+
- ✅ Memory (simple keyword matching - for testing only)
|
|
170
|
+
- ❌ Pinecone (not supported - use sparse vectors instead)
|
|
171
|
+
|
|
172
|
+
**Example:**
|
|
173
|
+
```ruby
|
|
174
|
+
# Keyword search for exact matches
|
|
175
|
+
results = client.text_search(
|
|
176
|
+
index: 'products',
|
|
177
|
+
text: 'iPhone 15 Pro',
|
|
178
|
+
top_k: 10,
|
|
179
|
+
filter: { category: 'electronics' }
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
results.each do |match|
|
|
183
|
+
puts "#{match.id}: #{match.score} - #{match.metadata['title']}"
|
|
184
|
+
end
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Use Cases:**
|
|
188
|
+
- Product name search (exact matches)
|
|
189
|
+
- Function/class name search in documentation
|
|
190
|
+
- Keyword-based filtering when semantic search is not needed
|
|
191
|
+
- Faster search when embeddings are not available
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
150
195
|
### `client.fetch(index:, ids:, namespace: nil)`
|
|
151
196
|
|
|
152
197
|
Fetch vectors by their IDs.
|
data/docs/api/overview.md
CHANGED
|
@@ -216,3 +216,9 @@ end
|
|
|
216
216
|
```
|
|
217
217
|
|
|
218
218
|
See [Complete API Methods Reference]({{ site.baseurl }}/api/methods/) for detailed method documentation.
|
|
219
|
+
|
|
220
|
+
## Next Steps
|
|
221
|
+
|
|
222
|
+
- [Providers Guide]({{ site.baseurl }}/providers/)
|
|
223
|
+
- [Rails Integration Guide]({{ site.baseurl }}/guides/rails-integration/)
|
|
224
|
+
- [Middleware System]({{ site.baseurl }}/guides/middleware/)
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: page
|
|
3
|
+
title: Middleware System
|
|
4
|
+
permalink: /guides/middleware/
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Middleware System
|
|
8
|
+
|
|
9
|
+
Vectra includes a **Rack-style middleware stack** that lets you extend the client
|
|
10
|
+
without forking the gem or patching providers.
|
|
11
|
+
|
|
12
|
+
You can:
|
|
13
|
+
|
|
14
|
+
- Add **logging, metrics, retries, PII redaction, cost tracking**.
|
|
15
|
+
- Inject **custom behaviour** before/after every operation.
|
|
16
|
+
- Enable features **globally** or **per client**, same kao Faraday/Sidekiq.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Core Concepts
|
|
21
|
+
|
|
22
|
+
### Request / Response
|
|
23
|
+
|
|
24
|
+
- **`Vectra::Middleware::Request`**
|
|
25
|
+
- `operation` – npr. `:upsert`, `:query`, `:fetch`, `:delete`, `:stats`, `:hybrid_search`
|
|
26
|
+
- `index` – ime indeksa (može biti `nil` ako koristiš default)
|
|
27
|
+
- `namespace` – namespace (može biti `nil`)
|
|
28
|
+
- `params` – originalni keyword parametri koje je `Vectra::Client` proslijedio
|
|
29
|
+
- `provider` – ime providera (`:pinecone`, `:qdrant`, `:pgvector`, `:memory`, …)
|
|
30
|
+
- helperi: `write_operation?`, `read_operation?`
|
|
31
|
+
|
|
32
|
+
- **`Vectra::Middleware::Response`**
|
|
33
|
+
- `result` – što god provider vrati (npr. hash, `QueryResult`, itd.)
|
|
34
|
+
- `error` – iznimka ako je došlo do greške
|
|
35
|
+
- `metadata` – slobodan hash za dodatne informacije (trajanje, cost, retry_count…)
|
|
36
|
+
- helperi: `success?`, `failure?`, `raise_if_error!`, `value!`
|
|
37
|
+
|
|
38
|
+
### Base i Stack
|
|
39
|
+
|
|
40
|
+
- **`Vectra::Middleware::Base`**
|
|
41
|
+
- Hookovi koje možeš override-ati:
|
|
42
|
+
- `before(request)` – prije poziva providera / sljedećeg middlewarea
|
|
43
|
+
- `after(request, response)` – nakon uspješnog poziva
|
|
44
|
+
- `on_error(request, error)` – kad dođe do iznimke (error se zatim re-raise-a)
|
|
45
|
+
|
|
46
|
+
- **`Vectra::Middleware::Stack`**
|
|
47
|
+
- Gradi chain oko konkretnog providera:
|
|
48
|
+
```ruby
|
|
49
|
+
stack = Vectra::Middleware::Stack.new(provider, [Logging.new, Retry.new])
|
|
50
|
+
result = stack.call(:upsert, index: "docs", vectors: [...], provider: :qdrant)
|
|
51
|
+
```
|
|
52
|
+
- `Stack` interno:
|
|
53
|
+
- kreira `Request`,
|
|
54
|
+
- kroz sve middlewares propagira isti `Request`,
|
|
55
|
+
- na kraju zove `provider.public_send(request.operation, **provider_params)`,
|
|
56
|
+
- vraća `Response` (s `result` ili `error`).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Enabling Middleware
|
|
61
|
+
|
|
62
|
+
### Global Middleware
|
|
63
|
+
|
|
64
|
+
Primjenjuje se na **sve** `Vectra::Client` instance.
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
require "vectra"
|
|
68
|
+
|
|
69
|
+
# Global logging + retry + cost tracking
|
|
70
|
+
Vectra::Client.use Vectra::Middleware::Logging
|
|
71
|
+
Vectra::Client.use Vectra::Middleware::Retry, max_attempts: 5
|
|
72
|
+
Vectra::Client.use Vectra::Middleware::CostTracker
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Sve sljedeće `Vectra::Client.new(...)` instance će koristiti ovaj globalni stack.
|
|
76
|
+
|
|
77
|
+
### Per‑Client Middleware
|
|
78
|
+
|
|
79
|
+
Dodatni ili prilagođeni middleware samo za jedan klijent:
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
client = Vectra::Client.new(
|
|
83
|
+
provider: :qdrant,
|
|
84
|
+
index: "products",
|
|
85
|
+
middleware: [
|
|
86
|
+
Vectra::Middleware::PIIRedaction,
|
|
87
|
+
Vectra::Middleware::Instrumentation
|
|
88
|
+
]
|
|
89
|
+
)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- Per‑client middleware se izvodi **nakon** globalnog, u istom chainu.
|
|
93
|
+
- Redoslijed u arrayu definira redoslijed ekzekucije (zadnji je najunutarnji, tik do providera).
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Koje operacije prolaze kroz stack?
|
|
98
|
+
|
|
99
|
+
Sve standardne operacije `Vectra::Client`a koriste middleware stack:
|
|
100
|
+
|
|
101
|
+
- `upsert`
|
|
102
|
+
- `query`
|
|
103
|
+
- `fetch`
|
|
104
|
+
- `update`
|
|
105
|
+
- `delete`
|
|
106
|
+
- `list_indexes`
|
|
107
|
+
- `describe_index`
|
|
108
|
+
- `stats`
|
|
109
|
+
- `hybrid_search`
|
|
110
|
+
|
|
111
|
+
To znači da middleware može:
|
|
112
|
+
|
|
113
|
+
- logirati / instrumentirati **sve pozive** prema provideru,
|
|
114
|
+
- raditi **PII redakciju** na `upsert` zahtjevima,
|
|
115
|
+
- brojati i retry-ati i **read** i **write** operacije,
|
|
116
|
+
- računati trošak po operaciji (npr. za billing / budžete).
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Built‑in Middleware
|
|
121
|
+
|
|
122
|
+
### Logging (`Vectra::Middleware::Logging`)
|
|
123
|
+
|
|
124
|
+
**Što radi:**
|
|
125
|
+
- logira početak i kraj svake operacije (`operation`, `index`, `namespace`),
|
|
126
|
+
- mjeri trajanje i sprema ga u `response.metadata[:duration_ms]`.
|
|
127
|
+
|
|
128
|
+
**Konfiguracija:**
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
# Globalno
|
|
132
|
+
Vectra::Client.use Vectra::Middleware::Logging
|
|
133
|
+
|
|
134
|
+
# S custom loggerom
|
|
135
|
+
logger = Logger.new($stdout)
|
|
136
|
+
Vectra::Client.use Vectra::Middleware::Logging, logger: logger
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Tipična upotreba:** debugiranje, audit logovi, korelacija s HTTP logovima.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### Retry (`Vectra::Middleware::Retry`)
|
|
144
|
+
|
|
145
|
+
**Što radi:**
|
|
146
|
+
- automatski retry-a transient greške:
|
|
147
|
+
- `Vectra::RateLimitError`
|
|
148
|
+
- `Vectra::ConnectionError`
|
|
149
|
+
- `Vectra::TimeoutError`
|
|
150
|
+
- `Vectra::ServerError`
|
|
151
|
+
- koristi exponential ili linear backoff,
|
|
152
|
+
- upisuje broj retry-a u `response.metadata[:retry_count]`.
|
|
153
|
+
|
|
154
|
+
**Konfiguracija:**
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
# 3 pokušaja, exponential backoff (default)
|
|
158
|
+
Vectra::Client.use Vectra::Middleware::Retry
|
|
159
|
+
|
|
160
|
+
# 5 pokušaja, linearni backoff
|
|
161
|
+
Vectra::Client.use Vectra::Middleware::Retry,
|
|
162
|
+
max_attempts: 5,
|
|
163
|
+
backoff: :linear
|
|
164
|
+
|
|
165
|
+
# Fiksni delay 1.0s
|
|
166
|
+
Vectra::Client.use Vectra::Middleware::Retry,
|
|
167
|
+
max_attempts: 3,
|
|
168
|
+
backoff: 1.0
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Tipična upotreba:** zaštita od povremenih mrežnih problema i rate‑limit grešaka.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### Instrumentation (`Vectra::Middleware::Instrumentation`)
|
|
176
|
+
|
|
177
|
+
**Što radi:**
|
|
178
|
+
- emitira događaje preko postojećeg `Vectra::Instrumentation` sustava,
|
|
179
|
+
- prikuplja trajanje, status, error class, dodatni `metadata`.
|
|
180
|
+
|
|
181
|
+
**Primjer:**
|
|
182
|
+
|
|
183
|
+
```ruby
|
|
184
|
+
Vectra::Client.use Vectra::Middleware::Instrumentation
|
|
185
|
+
|
|
186
|
+
Vectra.on_operation do |event|
|
|
187
|
+
# event[:operation], event[:provider], event[:duration_ms], event[:success], ...
|
|
188
|
+
StatsD.timing("vectra.#{event[:operation]}", event[:duration_ms])
|
|
189
|
+
end
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Tipična upotreba:** integracija s Prometheus/Grafana, Datadog, New Relic…
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
### PII Redaction (`Vectra::Middleware::PIIRedaction`)
|
|
197
|
+
|
|
198
|
+
**Što radi:**
|
|
199
|
+
- prije `upsert` operacija prolazi kroz `vectors[:metadata]`,
|
|
200
|
+
- prepoznaje PII pattern-e (email, phone, SSN, credit card) i zamjenjuje ih placeholderom
|
|
201
|
+
npr. `[REDACTED_EMAIL]`, `[REDACTED_PHONE]`, itd.
|
|
202
|
+
|
|
203
|
+
**Primjer:**
|
|
204
|
+
|
|
205
|
+
```ruby
|
|
206
|
+
Vectra::Client.use Vectra::Middleware::PIIRedaction
|
|
207
|
+
|
|
208
|
+
client.upsert(
|
|
209
|
+
index: "sensitive",
|
|
210
|
+
vectors: [
|
|
211
|
+
{
|
|
212
|
+
id: "user-1",
|
|
213
|
+
values: [0.1, 0.2, 0.3],
|
|
214
|
+
metadata: {
|
|
215
|
+
email: "user@example.com",
|
|
216
|
+
phone: "555-1234",
|
|
217
|
+
note: "Contact at user@example.com"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Nakon `upsert`‑a, provider će vidjeti već **redaktirani** metadata.
|
|
225
|
+
|
|
226
|
+
**Custom patterni:**
|
|
227
|
+
|
|
228
|
+
```ruby
|
|
229
|
+
patterns = {
|
|
230
|
+
credit_card: /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/,
|
|
231
|
+
api_key: /sk-[a-zA-Z0-9]{32}/
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
Vectra::Client.use Vectra::Middleware::PIIRedaction, patterns: patterns
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Tipična upotreba:** GDPR, SOC2, PCI‑DSS okruženja gdje je zabranjen PII u vektor bazi.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
### CostTracker (`Vectra::Middleware::CostTracker`)
|
|
242
|
+
|
|
243
|
+
**Što radi:**
|
|
244
|
+
- procjenjuje trošak po operaciji na temelju providera i tipa operacije (`read` / `write`),
|
|
245
|
+
- upisuje trošak u `response.metadata[:cost_usd]`,
|
|
246
|
+
- opcionalno zove `on_cost` callback za real‑time praćenje.
|
|
247
|
+
|
|
248
|
+
**Primjer:**
|
|
249
|
+
|
|
250
|
+
```ruby
|
|
251
|
+
Vectra::Client.use Vectra::Middleware::CostTracker,
|
|
252
|
+
on_cost: ->(event) {
|
|
253
|
+
puts "💰 Cost: $#{event[:cost_usd].round(6)} for #{event[:operation]} (#{event[:provider]})"
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Custom pricing:**
|
|
258
|
+
|
|
259
|
+
```ruby
|
|
260
|
+
pricing = {
|
|
261
|
+
pinecone: { read: 0.0001, write: 0.0002 },
|
|
262
|
+
qdrant: { read: 0.00005, write: 0.0001 }
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
Vectra::Client.use Vectra::Middleware::CostTracker, pricing: pricing
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Tipična upotreba:** unutarnji billing, budget guardrails, cost dashboards.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Custom Middleware
|
|
273
|
+
|
|
274
|
+
Najjednostavniji način je naslijediti `Vectra::Middleware::Base` i override-ati hookove:
|
|
275
|
+
|
|
276
|
+
```ruby
|
|
277
|
+
class MyAuditMiddleware < Vectra::Middleware::Base
|
|
278
|
+
def before(request)
|
|
279
|
+
AuditLog.create!(
|
|
280
|
+
operation: request.operation,
|
|
281
|
+
index: request.index,
|
|
282
|
+
namespace: request.namespace,
|
|
283
|
+
provider: request.provider
|
|
284
|
+
)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def after(_request, response)
|
|
288
|
+
puts "Duration: #{response.metadata[:duration_ms]}ms"
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def on_error(request, error)
|
|
292
|
+
ErrorTracker.notify(error, context: { operation: request.operation })
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
Vectra::Client.use MyAuditMiddleware
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Savjeti:**
|
|
300
|
+
|
|
301
|
+
- Ne mijenjaj strukturu `request.params` na način koji provider ne očekuje.
|
|
302
|
+
- Svoje pomoćne podatke stavljaj u `response.metadata` ili `request.metadata`.
|
|
303
|
+
- Ako hvataš greške u `on_error`, **nemoj ih gutati** – middleware stack će ih ponovo baciti.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Primjer: `examples/middleware_demo.rb`
|
|
308
|
+
|
|
309
|
+
U repozitoriju imaš kompletan demo:
|
|
310
|
+
|
|
311
|
+
- konfigurira globalni stack (`Logging`, `Retry`, `CostTracker`),
|
|
312
|
+
- pokazuje per‑client PII redaction,
|
|
313
|
+
- definira custom `TimingMiddleware`,
|
|
314
|
+
- demonstrira kako izgleda output u konzoli.
|
|
315
|
+
|
|
316
|
+
Pokretanje:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
bundle exec ruby examples/middleware_demo.rb
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Ovaj demo je dobar “živi” primjer kako kombinirati više middleware-a u praksi.
|
|
323
|
+
|
|
324
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: page
|
|
3
|
+
title: Roadmap
|
|
4
|
+
permalink: /guides/roadmap/
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Vectra Roadmap
|
|
8
|
+
|
|
9
|
+
This page outlines the high-level roadmap for **vectra-client**, the unified Ruby client for vector databases.
|
|
10
|
+
|
|
11
|
+
The roadmap is intentionally focused on **production features** that make AI workloads reliable, observable, and easy to operate in Ruby.
|
|
12
|
+
|
|
13
|
+
## Near Term (1.x)
|
|
14
|
+
|
|
15
|
+
- **Reranking middleware**
|
|
16
|
+
- Middleware that can call external rerankers (e.g., Cohere, Jina, custom HTTP) and reorder search results after a `query`.
|
|
17
|
+
- Pluggable providers, configurable `top_n`, and safe fallbacks when reranking fails.
|
|
18
|
+
- **More middleware building blocks**
|
|
19
|
+
- Request sampling / tracing for debugging complex production issues.
|
|
20
|
+
- Response shaping (e.g., score normalization, custom thresholds) as reusable middleware.
|
|
21
|
+
- **Rails UX improvements**
|
|
22
|
+
- Convenience generators and helpers for multi-tenant setups.
|
|
23
|
+
- Better defaults and examples for 1k+ records demos (e‑commerce, blogs, RAG, recommendations).
|
|
24
|
+
|
|
25
|
+
## Mid Term
|
|
26
|
+
|
|
27
|
+
- **Additional providers**
|
|
28
|
+
- Support for more hosted / self-hosted vector solutions where it makes sense and stays maintainable.
|
|
29
|
+
- **First-class reranking guides**
|
|
30
|
+
- End-to-end documentation for combining vectra-client with external LLMs / rerankers.
|
|
31
|
+
- **More recipes & patterns**
|
|
32
|
+
- Deeper recipes for analytics, recommendations, and hybrid search in large Rails apps.
|
|
33
|
+
|
|
34
|
+
## Long Term Vision
|
|
35
|
+
|
|
36
|
+
Keep **vectra-client** the most **production-ready Ruby toolkit** for vector databases:
|
|
37
|
+
|
|
38
|
+
- Strong guarantees around retries, circuit breakers, and backpressure.
|
|
39
|
+
- Excellent observability out of the box.
|
|
40
|
+
- Stable, provider-agnostic API that lets you change infra without rewriting your app.
|
|
41
|
+
|
|
42
|
+
If you have ideas or needs that fit this direction, please open an issue on GitHub so we can prioritise the roadmap around real-world use cases.
|
|
43
|
+
|
|
44
|
+
{
|
|
45
|
+
"cells": [],
|
|
46
|
+
"metadata": {
|
|
47
|
+
"language_info": {
|
|
48
|
+
"name": "python"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"nbformat": 4,
|
|
52
|
+
"nbformat_minor": 2
|
|
53
|
+
}
|