emb 0.1.0.pre.fix

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a8986240f45d756adc3ca4ca7ac920b9f2f4e9c9f2203c62d703f4ceb30df7cb
4
+ data.tar.gz: 0d5873987e49ef44ea775d26bd7b13f3110e38b0ee92838ef704caa5cc245f37
5
+ SHA512:
6
+ metadata.gz: 60b3d4a9ab3a57c6b101bb4093447ed0516f7850c7a83af5810a4289e76871bdb26c57cc93c3e2ff4565c0de341e02755ac5478cd152677dabcfea8e8f5669c1
7
+ data.tar.gz: 2e9a0eb3cc8f1f9ab61b10c6c91eb17f0d6f732048a233b788d920938a9a036923c0c2075b3bb2378bb32f3c1fc82c591672273e6f768036ebd334410016ca59
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ gem 'connection_pool'
8
+ gem 'redis-client'
9
+
10
+ gem 'rake', require: false
11
+ gem 'rspec', require: false
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # emb — Ruby client
2
+
3
+ Thin Ruby wrapper for [emb](https://github.com/elcuervo/emb), a Redis-compatible embedding server.
4
+
5
+ ## Usage
6
+
7
+ ```ruby
8
+ require "emb"
9
+
10
+ Emb.setup(host: "localhost", port: 6379, pool: 5)
11
+
12
+ Emb[:minilm]["hello world"]
13
+ # → raw float32 bytes
14
+
15
+ Emb.models
16
+ # → [{name: "minilm", dim: 384, status: "ready"}, ...]
17
+
18
+ Emb.info(:minilm)
19
+ # → {dim: 384, workers: 10, ...}
20
+
21
+ Emb.multi do |m|
22
+ m[:minilm]["hello"]
23
+ m[:bge]["world"]
24
+ end
25
+ # → EMB.MULTI minilm "hello" bge "world"
26
+ ```
27
+
28
+ ## Testing end to end
29
+
30
+ ### Prerequisites
31
+
32
+ - An `emb` binary built from the repo root (`just build` or `go build`)
33
+ - Ruby 3.3+ with bundler
34
+
35
+ ### Running tests
36
+
37
+ ```bash
38
+ # From the repo root, start the emb server:
39
+ ./bin/emb -config test-two-models.yaml &
40
+
41
+ # From gems/emb/, run the test suite:
42
+ bundle exec rake
43
+ ```
44
+
45
+ This starts the full test suite against a real running `emb` server. Tests cover all commands: `EMB`, `EMB.MODELS`, `EMB.INFO`, `EMB.HELP`, `PING`, and `EMB.MULTI`.
data/lib/emb/client.rb ADDED
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "connection_pool"
4
+ require "redis_client"
5
+
6
+ module Emb
7
+ @pool = nil
8
+
9
+ DEFAULTS = {host: "localhost", port: 6379, pool: 5}.freeze
10
+
11
+ class << self
12
+ def setup(host: DEFAULTS[:host], port: DEFAULTS[:port], pool: DEFAULTS[:pool])
13
+ @pool = ConnectionPool.new(size: pool) do
14
+ RedisClient.new(host: host, port: port, protocol: 2, reconnect_attempts: 3)
15
+ end
16
+ end
17
+ alias_method :config, :setup
18
+
19
+ def send_command(*args)
20
+ pool.with { |r| r.call(*args) }
21
+ end
22
+
23
+ private
24
+
25
+ def pool
26
+ @pool ||= default_pool
27
+ end
28
+
29
+ def default_pool
30
+ ConnectionPool.new(size: DEFAULTS[:pool]) do
31
+ RedisClient.new(host: DEFAULTS[:host], port: DEFAULTS[:port], protocol: 2, reconnect_attempts: 3)
32
+ end
33
+ end
34
+ end
35
+ end
data/lib/emb/multi.rb ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Emb
4
+ class MultiProxy
5
+ def initialize
6
+ @pairs = []
7
+ end
8
+
9
+ def [](name)
10
+ PairCollector.new(@pairs, name.to_sym)
11
+ end
12
+
13
+ def run
14
+ args = @pairs.flat_map { |pair| [pair[:model].to_s, pair[:text]] }
15
+ Emb.send_command("EMB.MULTI", *args)
16
+ end
17
+
18
+ class PairCollector
19
+ def initialize(pairs, model)
20
+ @pairs = pairs
21
+ @model = model
22
+ end
23
+
24
+ def [](text)
25
+ @pairs << {model: @model, text: text}
26
+ end
27
+ end
28
+ end
29
+
30
+ class << self
31
+ def multi
32
+ mp = MultiProxy.new
33
+ yield mp
34
+ mp.run
35
+ end
36
+ end
37
+ end
data/lib/emb/proxy.rb ADDED
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Emb
4
+ @registry = {}
5
+
6
+ class << self
7
+ def [](name)
8
+ @registry[name] ||= Proxy.new(name.to_sym)
9
+ end
10
+
11
+ def reset_registry!
12
+ @registry.clear
13
+ end
14
+ end
15
+
16
+ class Proxy
17
+ attr_reader :name
18
+
19
+ def initialize(name)
20
+ @name = name
21
+ end
22
+
23
+ def [](text, *texts)
24
+ Emb.send_command("EMB", @name.to_s, text, *texts)
25
+ end
26
+
27
+ def inspect
28
+ "#<Emb::Proxy #{@name}>"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Emb
4
+ VERSION =
5
+ begin
6
+ File.read(File.expand_path('../../../../VERSION', __dir__)).strip
7
+ rescue Errno::ENOENT
8
+ Gem::Specification.find_by_name("emb").version.to_s
9
+ end
10
+ end
data/lib/emb.rb ADDED
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "emb/version"
4
+ require_relative "emb/client"
5
+ require_relative "emb/proxy"
6
+ require_relative "emb/multi"
7
+
8
+ module Emb
9
+ class << self
10
+ def models
11
+ raw = send_command("EMB.MODELS")
12
+ return [] if raw.nil?
13
+ raw.map { |name, dim, status| {name: name, dim: dim.to_i, status: status} }
14
+ end
15
+
16
+ def info(name)
17
+ raw = send_command("EMB.INFO", name.to_s)
18
+
19
+ return {} if raw.nil?
20
+
21
+ raw.each_slice(2).map { |k, v| [k.to_sym, v] }.to_h
22
+ end
23
+
24
+ def stats = send_command("EMB.STATS")
25
+
26
+ def help = send_command("EMB.HELP")
27
+
28
+ def ping = send_command("PING")
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: emb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre.fix
5
+ platform: ruby
6
+ authors:
7
+ - elcuervo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-07-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: connection_pool
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: redis-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.24'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.24'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.13'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.13'
55
+ description:
56
+ email:
57
+ - elcuervo@elcuervo.net
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - Gemfile
63
+ - README.md
64
+ - lib/emb.rb
65
+ - lib/emb/client.rb
66
+ - lib/emb/multi.rb
67
+ - lib/emb/proxy.rb
68
+ - lib/emb/version.rb
69
+ homepage: https://github.com/elcuervo/emb
70
+ licenses:
71
+ - MIT
72
+ metadata:
73
+ rubygems_mfa_required: 'true'
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '3.3'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubygems_version: 3.5.22
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: 'Client for emb: a Redis-compatible embedding server'
93
+ test_files: []