emb 0.4.0.pre5 → 0.4.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 +4 -4
- data/LICENSE +21 -0
- data/README.md +6 -1
- data/lib/emb/client.rb +12 -14
- data/lib/emb/configuration.rb +13 -0
- data/lib/emb/proxy.rb +12 -11
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 99633d8ba61adbf0de6c6fb915f2505ac67298d1a30d070808bb443e65c19aed
|
|
4
|
+
data.tar.gz: 847e2df69be7a2c228faf9207d8f3ca92c7b6e4b93762bb3160db9b0253de9af
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7c34b36d11f4a3cc86087d6d8d973f4ab791ad3ce02d22031fabce0e3e842a7d73a8bc545b1cb68e8bf56ca67d1e3f63ca6e6e3256b5e14c2d9ffadcdc5b3978
|
|
7
|
+
data.tar.gz: 6c70ec162e9740745c976cba443ead4d99809c365b4d0729291d56d525d297c76eeb4d057e938febda1f56b066bab1f0859f89de656584f6c975c1f0b2bf054c
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 elcuervo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -70,7 +70,10 @@ Emb::Client.new(pool: 20) # per-call still wins
|
|
|
70
70
|
The shipped defaults are benchmark-derived (see `BENCHMARK.md`) with secure-by-default
|
|
71
71
|
network behavior: **eager execution by default** (`lazy: false` — every `Emb[:model][t]`
|
|
72
72
|
sends one `EMB` round trip), pool `5`, pure-Ruby RESP driver, `protocol: 2`,
|
|
73
|
-
`read_timeout`/`write_timeout` both **10s**, and `reconnect_attempts: 0`.
|
|
73
|
+
`read_timeout`/`write_timeout` both **10s**, and `reconnect_attempts: 0`. `protocol: 2`
|
|
74
|
+
is the only supported value: the gem speaks RESP2 and does not decode the RESP3 maps the
|
|
75
|
+
server emits for `EMB.MODELS`, `EMB.STATS`, `EMB.INFO`, and `CONFIG GET`, so setting any
|
|
76
|
+
other value raises `ArgumentError`. Opt into
|
|
74
77
|
coalescing with `lazy: :multi` or concurrent fan-out with `lazy: :batch` — globally via
|
|
75
78
|
`Emb.configure { |c| c.lazy = :batch }` or per client with `Emb.new(lazy: :batch)`.
|
|
76
79
|
|
|
@@ -215,6 +218,8 @@ Emb.info(:minilm) # model info
|
|
|
215
218
|
Emb.stats # server stats (Hash of key => value)
|
|
216
219
|
Emb.help # command reference
|
|
217
220
|
Emb.ping # health check
|
|
221
|
+
Emb.ready? # true only when EMB.READY answers OK (false when not ready or unreachable)
|
|
222
|
+
Emb.ready # status string: "OK", or the server/connection error text
|
|
218
223
|
```
|
|
219
224
|
|
|
220
225
|
These all delegate to a lazily-initialized default client. No explicit `setup` call
|
data/lib/emb/client.rb
CHANGED
|
@@ -66,18 +66,14 @@ module Emb
|
|
|
66
66
|
|
|
67
67
|
def ready
|
|
68
68
|
send_command('EMB.READY')
|
|
69
|
-
|
|
70
|
-
'ready'
|
|
71
|
-
rescue RedisClient::CommandError => e
|
|
69
|
+
rescue RedisClient::Error => e
|
|
72
70
|
e.message
|
|
73
71
|
end
|
|
74
72
|
|
|
73
|
+
# True only when the server answers EMB.READY with OK; #ready folds any
|
|
74
|
+
# Redis error (including a refused connection) into a string.
|
|
75
75
|
def ready?
|
|
76
|
-
ready
|
|
77
|
-
|
|
78
|
-
true
|
|
79
|
-
rescue RedisClient::CommandError
|
|
80
|
-
false
|
|
76
|
+
ready == 'OK'
|
|
81
77
|
end
|
|
82
78
|
|
|
83
79
|
def reset_registry!
|
|
@@ -100,12 +96,7 @@ module Emb
|
|
|
100
96
|
value
|
|
101
97
|
end
|
|
102
98
|
|
|
103
|
-
|
|
104
|
-
raise ArgumentError, 'url array must not be empty' if url.is_a?(Array) && url.empty?
|
|
105
|
-
|
|
106
|
-
url.nil? ? [nil] : Array(url)
|
|
107
|
-
end
|
|
108
|
-
|
|
99
|
+
# Per-call protocol: bypasses Configuration#protocol=, so validate here too.
|
|
109
100
|
def merged_redis_options(opts, cfg, url)
|
|
110
101
|
defaults = cfg.to_h
|
|
111
102
|
keys = defaults.keys - %i[url pool lazy batch_size]
|
|
@@ -115,9 +106,16 @@ module Emb
|
|
|
115
106
|
opts[key] = defaults[key] if opts[key].nil? && !defaults[key].nil?
|
|
116
107
|
end
|
|
117
108
|
|
|
109
|
+
Configuration.validate_protocol!(opts[:protocol])
|
|
118
110
|
opts
|
|
119
111
|
end
|
|
120
112
|
|
|
113
|
+
def instance_urls(url)
|
|
114
|
+
raise ArgumentError, 'url array must not be empty' if url.is_a?(Array) && url.empty?
|
|
115
|
+
|
|
116
|
+
url.nil? ? [nil] : Array(url)
|
|
117
|
+
end
|
|
118
|
+
|
|
121
119
|
def extract_url!(opts, cfg)
|
|
122
120
|
url = opts.delete(:url)
|
|
123
121
|
return url unless url.nil?
|
data/lib/emb/configuration.rb
CHANGED
|
@@ -23,6 +23,19 @@ module Emb
|
|
|
23
23
|
@lazy = value
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
# The gem speaks RESP2 only: its models/stats/info/config decoders assume
|
|
27
|
+
# flat RESP2 arrays, and RESP3 maps would silently return wrong results.
|
|
28
|
+
def self.validate_protocol!(value)
|
|
29
|
+
return if value == 2
|
|
30
|
+
|
|
31
|
+
raise ArgumentError, "protocol must be 2 (RESP2 only; RESP3 is not decoded), got #{value.inspect}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def protocol=(value)
|
|
35
|
+
self.class.validate_protocol!(value)
|
|
36
|
+
@protocol = value
|
|
37
|
+
end
|
|
38
|
+
|
|
26
39
|
def initialize
|
|
27
40
|
self.host = 'localhost'
|
|
28
41
|
self.port = 6379
|
data/lib/emb/proxy.rb
CHANGED
|
@@ -21,17 +21,9 @@ module Emb
|
|
|
21
21
|
if @client.lazy?
|
|
22
22
|
return Emb.build_batch_loader(@client, @name, texts.empty? ? text : [text, *texts], format: format)
|
|
23
23
|
end
|
|
24
|
+
return values_query(text, texts) if format == :values
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
return values_query(text, texts)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
set = Array(@client.send_command('EMB', @name.to_s, text, *texts))
|
|
30
|
-
result = set.map { |entry| entry.unpack('e*') }
|
|
31
|
-
|
|
32
|
-
return result.first if result.size == 1
|
|
33
|
-
|
|
34
|
-
result
|
|
26
|
+
unpack_set(@client.send_command('EMB', @name.to_s, text, *texts))
|
|
35
27
|
end
|
|
36
28
|
|
|
37
29
|
def inspect
|
|
@@ -79,8 +71,17 @@ module Emb
|
|
|
79
71
|
|
|
80
72
|
private
|
|
81
73
|
|
|
74
|
+
# One packed vector for a single text, an array for several; a null slot
|
|
75
|
+
# (failed/truncated position) maps to nil.
|
|
76
|
+
def unpack_set(raw)
|
|
77
|
+
return nil if raw.nil?
|
|
78
|
+
|
|
79
|
+
result = Array(raw).map { |entry| entry&.unpack('e*') }
|
|
80
|
+
result.size == 1 ? result.first : result
|
|
81
|
+
end
|
|
82
|
+
|
|
82
83
|
def unpack_embedding(entry)
|
|
83
|
-
entry
|
|
84
|
+
entry&.unpack('e*')
|
|
84
85
|
end
|
|
85
86
|
|
|
86
87
|
def normalize_format(format)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: emb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.0
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- elcuervo
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: batch-loader
|
|
@@ -46,6 +46,7 @@ extensions: []
|
|
|
46
46
|
extra_rdoc_files: []
|
|
47
47
|
files:
|
|
48
48
|
- Gemfile
|
|
49
|
+
- LICENSE
|
|
49
50
|
- README.md
|
|
50
51
|
- lib/emb.rb
|
|
51
52
|
- lib/emb/batch.rb
|