vectra-client 0.4.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0d48b8a6205df9a0d6545e3772e26da09f826f03d56751a6fa997e1a73d89f1
4
- data.tar.gz: 25dc65ad327e03e7912a0b938739b6acf1d6708efd8fa41773d9bbae1053e3dc
3
+ metadata.gz: b28b595dca76f398f7214341af084ae1f344087d09f2a3933228bf8d006f4ec5
4
+ data.tar.gz: 9e5c7344a204724914746545042d30618b01c23287178f1abce8e75050c9628e
5
5
  SHA512:
6
- metadata.gz: 68fc7d7a2c941733bb8f42007dffa52989daedeb362da62c094d05dec7d02f8ca6d7ca8763194e9b51b4ecfe3f7a6e8db4418c7589caab31943f055f75f4c48a
7
- data.tar.gz: f40ab28eb011943d4961e22c5d31b5a816a81cea1a2bf6afa238004adaa1cdd8558f10b0ee8d56376d6fc737788b16fc1acb7088778d8461ecb3a8db2ff85580
6
+ metadata.gz: ecece93b7ab73710d5ac3718a8c6829b8a93d51e801aa4ad93ce85ab61fd129fed6ec66e138a1427fe2b2fbc9d9501998d38c1362363a1790b650a0d3aedfc66
7
+ data.tar.gz: 8b10e152ca8fcf573bf45e61cd887c9648c17ace9d8516f660448178c33e1904dce700271f33dd0b64374a63702f70c3f0e75a5ea40b673ba223e2d4c1ff117d
data/CHANGELOG.md CHANGED
@@ -1,19 +1,17 @@
1
1
  # Changelog
2
2
 
3
- ## [v0.4.0](https://github.com/stokry/vectra/tree/v0.4.0) (2026-01-12)
4
-
5
- ### Added
6
- - Memory provider for in-memory vector storage
7
- - QueryBuilder for chainable query API
8
- - Batch operations with concurrent processing
9
- - Vector normalization methods (L2, L1)
10
- - Enhanced error message extraction
3
+ ## [v1.0.1](https://github.com/stokry/vectra/tree/v1.0.1) (2026-01-13)
11
4
 
12
5
  ### Fixed
13
- - Weaviate DELETE request query parameters
14
- - Qdrant error message extraction from nested status
15
- - Client ping error info capture
16
- - Credential rotation timeout parameter handling
6
+ - Fix RuboCop violations in index generator
7
+
8
+ [Full Changelog](https://github.com/stokry/vectra/compare/v1.0.0...v1.0.1)
9
+
10
+ ## [v1.0.0](https://github.com/stokry/vectra/tree/v1.0.0) (2026-01-12)
11
+
12
+ [Full Changelog](https://github.com/stokry/vectra/compare/v0.4.0...v1.0.0)
13
+
14
+ ## [v0.4.0](https://github.com/stokry/vectra/tree/v0.4.0) (2026-01-12)
17
15
 
18
16
  [Full Changelog](https://github.com/stokry/vectra/compare/v0.3.4...v0.4.0)
19
17
 
data/README.md CHANGED
@@ -1,13 +1,32 @@
1
- # Vectra
2
-
3
- [![Gem Version](https://badge.fury.io/rb/vectra-client.svg)](https://rubygems.org/gems/vectra-client)
4
- [![CI](https://github.com/stokry/vectra/actions/workflows/ci.yml/badge.svg)](https://github.com/stokry/vectra/actions)
5
- [![codecov](https://codecov.io/gh/stokry/vectra/branch/main/graph/badge.svg)](https://codecov.io/gh/stokry/vectra)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
-
8
- **A unified Ruby client for vector databases.** Write once, switch providers seamlessly.
9
-
10
- 📖 **Documentation:** [vectra-docs.netlify.app](https://vectra-docs.netlify.app/)
1
+ # Vectra client
2
+
3
+ <p align="center">
4
+ <img src="docs/assets/readme-new.png" alt="Vectra – Unified Ruby client for vector databases" width="340">
5
+ </p>
6
+
7
+ <p align="center">
8
+ <a href="https://rubygems.org/gems/vectra-client">
9
+ <img src="https://badge.fury.io/rb/vectra-client.svg" alt="Gem Version">
10
+ </a>
11
+ <a href="https://github.com/stokry/vectra/actions">
12
+ <img src="https://github.com/stokry/vectra/actions/workflows/ci.yml/badge.svg" alt="CI">
13
+ </a>
14
+ <a href="https://codecov.io/gh/stokry/vectra">
15
+ <img src="https://codecov.io/gh/stokry/vectra/branch/main/graph/badge.svg" alt="codecov">
16
+ </a>
17
+ <a href="https://opensource.org/licenses/MIT">
18
+ <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License">
19
+ </a>
20
+ </p>
21
+
22
+ <p align="center">
23
+ <strong>A unified Ruby client for vector databases.</strong><br>
24
+ Write once, switch providers seamlessly.
25
+ </p>
26
+
27
+ <p align="center">
28
+ 📖 <strong>Documentation:</strong> <a href="https://vectra-docs.netlify.app/">vectra-docs.netlify.app</a>
29
+ </p>
11
30
 
12
31
  ## Supported Providers
13
32
 
@@ -81,6 +100,15 @@ end
81
100
  # Ping with latency
82
101
  status = client.ping
83
102
  puts "Provider: #{status[:provider]}, Latency: #{status[:latency_ms]}ms"
103
+
104
+ # Hybrid search (semantic + keyword)
105
+ # Supported by: Qdrant, Weaviate, Pinecone, pgvector
106
+ results = client.hybrid_search(
107
+ index: 'docs',
108
+ vector: embedding,
109
+ text: 'ruby programming',
110
+ alpha: 0.7 # 70% semantic, 30% keyword
111
+ )
84
112
  ```
85
113
 
86
114
  ## Provider Examples
@@ -108,13 +136,51 @@ client = Vectra.pgvector(connection_url: 'postgres://user:pass@localhost/mydb')
108
136
  client = Vectra.memory
109
137
  ```
110
138
 
139
+ ## Architecture Overview
140
+
141
+ ```mermaid
142
+ graph TB
143
+ A[Vectra Client] --> B[Unified API]
144
+ B --> C[Pinecone]
145
+ B --> D[Qdrant]
146
+ B --> E[Weaviate]
147
+ B --> F[pgvector]
148
+ B --> G[Memory]
149
+
150
+ H[Production Patterns] --> I[Circuit Breaker]
151
+ H --> J[Rate Limiter]
152
+ H --> K[Retry Logic]
153
+ H --> L[Instrumentation]
154
+
155
+ A --> H
156
+
157
+ style A fill:#05df72
158
+ style B fill:#2ee889
159
+ style H fill:#04b85e
160
+ ```
161
+
111
162
  ## Features
112
163
 
113
- - **Provider Agnostic** - Switch providers with one line change
114
- - **Production Ready** - Ruby 3.2+, 95%+ test coverage
115
- - **Resilient** - Retry logic with exponential backoff
116
- - **Observable** - Datadog & New Relic instrumentation
117
- - **Rails Ready** - ActiveRecord integration with `has_vector` DSL
164
+ - **🔌 Provider Agnostic** - Switch between 5 providers with one line change
165
+ - **🚀 Production Ready** - Ruby 3.2+, 95%+ test coverage, enterprise patterns
166
+ - **🛡️ Resilient** - Circuit breaker, rate limiter, retry logic with exponential backoff
167
+ - **📈 Observable** - Grafana dashboards, Prometheus metrics, 4 instrumentation backends
168
+ - **🏗️ Rails Ready** - ActiveRecord integration with `has_vector` DSL
169
+ - **🔍 Hybrid Search** - Semantic + keyword search across 4 providers
170
+ - **🧪 Testing** - Built-in mock provider for easy testing
171
+ - **⚡ Performance** - Connection pooling, caching, async batch operations
172
+
173
+ ## 📊 Why Vectra?
174
+
175
+ | What You Get | Vectra | Others |
176
+ |--------------|--------|--------|
177
+ | **Providers** | 5 unified | 1 each |
178
+ | **Production Patterns** | ✅ 7 built-in | ❌ Manual |
179
+ | **Testing** | ✅ Mock provider | ❌ External DB |
180
+ | **Rails** | ✅ `has_vector` DSL | ⚠️ Manual |
181
+ | **Observability** | ✅ 4 backends | ❌ DIY |
182
+
183
+ [→ See full comparison](https://vectra-docs.netlify.app)
118
184
 
119
185
  ## Rails Integration
120
186
 
@@ -135,6 +201,33 @@ doc = Document.create!(title: 'Hello', embedding: [0.1, 0.2, ...])
135
201
  Document.vector_search(embedding: query_vector, limit: 10)
136
202
  ```
137
203
 
204
+ ### Rails Generator: vectra:index
205
+
206
+ Generate everything you need for a model with a single command:
207
+
208
+ ```bash
209
+ rails generate vectra:index Product embedding dimension:1536 provider:qdrant
210
+ ```
211
+
212
+ This will:
213
+
214
+ - **Create a pgvector migration** (only when `provider=pgvector`) adding `embedding` column
215
+ - **Generate a model concern** (`ProductVector`) with `has_vector :embedding`
216
+ - **Update the model** to include `ProductVector`
217
+ - **Append to `config/vectra.yml`** with index metadata (no API keys)
218
+
219
+ ## Production Patterns
220
+
221
+ Vectra includes 7 production-ready patterns out of the box:
222
+
223
+ - **Circuit Breaker** - Automatic failover when providers are down
224
+ - **Rate Limiter** - Token bucket algorithm to prevent API throttling
225
+ - **Retry Logic** - Exponential backoff with jitter
226
+ - **Connection Pooling** - Efficient connection management (pgvector)
227
+ - **Caching** - LRU cache with TTL for frequently queried vectors
228
+ - **Health Checks** - `healthy?`, `ping`, and `health_check` methods
229
+ - **Instrumentation** - Datadog, New Relic, Sentry, Honeybadger support
230
+
138
231
  ## Development
139
232
 
140
233
  ```bash
@@ -5,11 +5,106 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <meta name="description" content="{{ page.description | default: site.description }}">
7
7
  <title>{{ page.title }} - {{ site.title }}</title>
8
+
9
+ <!-- Primary styles -->
8
10
  <link rel="stylesheet" href="{{ site.baseurl }}/assets/style.css">
9
- <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>◆</text></svg>">
11
+
12
+ <!-- Favicon -->
13
+ <link rel="icon" type="image/svg+xml" href="{{ site.baseurl }}/assets/favicon.svg">
14
+
15
+ <!-- SEO Meta -->
16
+ <meta property="og:title" content="{{ page.title | default: site.title }}">
17
+ <meta property="og:description" content="{{ page.description | default: site.description }}">
18
+ <meta property="og:type" content="website">
19
+ <meta property="og:url" content="{{ page.url | absolute_url }}">
20
+ <meta property="og:image" content="{{ site.url }}{{ site.baseurl }}/assets/seo.png">
21
+
22
+ <meta name="twitter:card" content="summary_large_image">
23
+ <meta name="twitter:title" content="{{ page.title | default: site.title }}">
24
+ <meta name="twitter:description" content="{{ page.description | default: site.description }}">
25
+ <meta name="twitter:image" content="{{ site.url }}{{ site.baseurl }}/assets/seo.png">
26
+
10
27
  <script defer src="https://umami-production-dfb8.up.railway.app/script.js" data-website-id="07e5420c-12d1-4e3c-9dbd-5cecb15a878f"></script>
11
28
  </head>
12
29
  <body>
13
- {{ content }}
30
+ <!-- Header -->
31
+ <header class="tma-header">
32
+ <nav class="tma-nav">
33
+ <a href="{{ site.baseurl }}/" class="tma-nav__brand">
34
+ <img src="{{ site.baseurl }}/assets/logo.svg" alt="Vectra" class="tma-nav__logo">
35
+ </a>
36
+ <button class="tma-nav__toggle" aria-label="Toggle menu" aria-expanded="false">
37
+ <span class="tma-nav__toggle-line"></span>
38
+ <span class="tma-nav__toggle-line"></span>
39
+ <span class="tma-nav__toggle-line"></span>
40
+ </button>
41
+ <ul class="tma-nav__menu" id="nav-menu">
42
+ <li><a href="{{ site.baseurl }}/guides/getting-started" class="tma-nav__link">Getting Started</a></li>
43
+ <li><a href="{{ site.baseurl }}/providers" class="tma-nav__link">Providers</a></li>
44
+ <li><a href="{{ site.baseurl }}/api/overview" class="tma-nav__link">API</a></li>
45
+ <li><a href="{{ site.baseurl }}/examples" class="tma-nav__link">Examples</a></li>
46
+ <li><a href="https://github.com/stokry/vectra" target="_blank" class="tma-nav__link tma-nav__link--github">
47
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>
48
+ GitHub
49
+ </a></li>
50
+ </ul>
51
+ </nav>
52
+ </header>
53
+
54
+ <main style="padding-top: var(--tma-header-height);">
55
+ {{ content }}
56
+ </main>
57
+
58
+ <!-- Footer -->
59
+ <footer class="tma-footer">
60
+ <div class="tma-footer__container">
61
+ <div>
62
+ <span class="tma-footer__brand">◆ Vectra</span>
63
+ <p class="tma-footer__copy">Built with ❤️ for the Ruby community. Mijo Kristo</p>
64
+ </div>
65
+ <ul class="tma-footer__links">
66
+ <li><a href="https://github.com/stokry/vectra">GitHub</a></li>
67
+ <li><a href="https://rubygems.org/gems/vectra-client">RubyGems</a></li>
68
+ <li><a href="{{ site.baseurl }}/community/contributing">Contributing</a></li>
69
+ <li><a href="https://github.com/stokry/vectra/blob/main/LICENSE">MIT License</a></li>
70
+ </ul>
71
+ </div>
72
+ </footer>
73
+
74
+ <script>
75
+ document.addEventListener('DOMContentLoaded', function() {
76
+ const navToggle = document.querySelector('.tma-nav__toggle');
77
+ const navMenu = document.querySelector('.tma-nav__menu');
78
+
79
+ if (navToggle && navMenu) {
80
+ navToggle.addEventListener('click', function(e) {
81
+ e.preventDefault();
82
+ e.stopPropagation();
83
+ const isExpanded = navToggle.getAttribute('aria-expanded') === 'true';
84
+ navToggle.setAttribute('aria-expanded', !isExpanded);
85
+ navMenu.classList.toggle('tma-nav__menu--open');
86
+ });
87
+
88
+ // Close menu when clicking on a link
89
+ const navLinks = navMenu.querySelectorAll('.tma-nav__link');
90
+ navLinks.forEach(function(link) {
91
+ link.addEventListener('click', function() {
92
+ navToggle.setAttribute('aria-expanded', 'false');
93
+ navMenu.classList.remove('tma-nav__menu--open');
94
+ });
95
+ });
96
+
97
+ // Close menu when clicking outside
98
+ document.addEventListener('click', function(e) {
99
+ if (navMenu.classList.contains('tma-nav__menu--open') &&
100
+ !navMenu.contains(e.target) &&
101
+ !navToggle.contains(e.target)) {
102
+ navToggle.setAttribute('aria-expanded', 'false');
103
+ navMenu.classList.remove('tma-nav__menu--open');
104
+ }
105
+ });
106
+ }
107
+ });
108
+ </script>
14
109
  </body>
15
110
  </html>