llm.rb 0.17.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fcb896bf97c2b2a07987e7d44088244e79bf35220478dd3ac93fc349a91c5f7c
4
- data.tar.gz: e33c4f4c87d72568ac94af0f4494e6a40ade164dbc894de1c772fc1bd6c92705
3
+ metadata.gz: 143a4329539a3ac3f9ece7925f5aef3061ee4aee4562e251c1ee1b4f21ec834a
4
+ data.tar.gz: 538019c363e178fff1ac8afec1c76cabcd23cbc05b212641251feb072d200958
5
5
  SHA512:
6
- metadata.gz: 660dee96aa651f293818492ab74efa92893cf2f39dc43dd04c84841ca13071769cabf5ee03060406295af6759ed005e76594abb0de1b6b4d00b1a0b5f0915284
7
- data.tar.gz: 89166bce1fb90718b8b99e2a8b6bea1fbe3cbbeb33c7fdcb0362febc7f969caaaab7e5072514793ebc8e911d7c98ebe9f46ec0b7d29257a299e9e99fca497a15
6
+ metadata.gz: 70da6593671516e75b0a7f0813ee2d50ab9dceddfecda072465e435bad8964aa9eb6fb539dff6ff3846872f3ff18f3648b726016e164ab3a5b852d6b2edc8068
7
+ data.tar.gz: 4c473fe9e13b0b9ce2219c3c2023237860e0d77df44d408a6d8bed4f747e7169e6541303cb7823aa727aaec4f578c5579b40120921231aaf6ea2b9b568435159
data/README.md CHANGED
@@ -1,9 +1,15 @@
1
+ > **Maintenance Notice** <br>
2
+ > Please note that the primary author of llm.rb is pivoting away from
3
+ > Ruby and towards [Golang](https://golang.org) for future projects.
4
+ > Although llm.rb will be maintained for the foreseeable future it is not
5
+ > where my primary interests lie anymore. Thanks for understanding.
6
+
1
7
  ## About
2
8
 
3
9
  llm.rb is a zero-dependency Ruby toolkit for Large Language Models that
4
- includes OpenAI, Gemini, Anthropic, xAI (Grok), DeepSeek, Ollama, and
5
- LlamaCpp. The toolkit includes full support for chat, streaming, tool calling,
6
- audio, images, files, and structured outputs (JSON Schema).
10
+ includes OpenAI, Gemini, Anthropic, xAI (Grok), [zAI](https://z.ai), DeepSeek,
11
+ Ollama, and LlamaCpp. The toolkit includes full support for chat, streaming,
12
+ tool calling, audio, images, files, and structured outputs (JSON Schema).
7
13
 
8
14
  ## Quick start
9
15
 
@@ -28,6 +34,8 @@ GitHub Copilot but for the terminal.
28
34
  a blog post that implements image editing with Gemini
29
35
  * [Fast sailing with persistent connections](https://0x1eef.github.io/posts/persistent-connections-with-llm.rb/) &ndash;
30
36
  a blog post that optimizes performance with a thread-safe connection pool
37
+ * [How to build agents (with llm.rb)](https://0x1eef.github.io/posts/how-to-build-agents-with-llm.rb/) &ndash;
38
+ a blog post that implements agentic behavior via tools
31
39
 
32
40
  #### Ecosystem
33
41
 
@@ -87,22 +95,22 @@ While the Features section above gives you the high-level picture, the table bel
87
95
  breaks things down by provider, so you can see exactly what’s supported where.
88
96
 
89
97
 
90
- | Feature / Provider | OpenAI | Anthropic | Gemini | DeepSeek | xAI (Grok) | Ollama | LlamaCpp |
91
- |--------------------------------------|:------:|:---------:|:------:|:--------:|:----------:|:------:|:--------:|
92
- | **Chat Completions** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
93
- | **Streaming** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
94
- | **Tool Calling** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
95
- | **JSON Schema / Structured Output** | ✅ | ❌ | ✅ | ❌ | ✅ | ✅* | ✅* |
96
- | **Embeddings** | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
97
- | **Multimodal Prompts** *(text, documents, audio, images, videos, URLs, etc)* | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
98
- | **Files API** | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
99
- | **Models API** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
100
- | **Audio (TTS / Transcribe / Translate)** | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
101
- | **Image Generation & Editing** | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ |
102
- | **Local Model Support** | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
103
- | **Vector Stores (RAG)** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
104
- | **Responses** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
105
- | **Moderations** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
98
+ | Feature / Provider | OpenAI | Anthropic | Gemini | DeepSeek | xAI (Grok) | zAI | Ollama | LlamaCpp |
99
+ |--------------------------------------|:------:|:---------:|:------:|:--------:|:----------:|:------:|:------:|:--------:|
100
+ | **Chat Completions** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
101
+ | **Streaming** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
102
+ | **Tool Calling** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
103
+ | **JSON Schema / Structured Output** | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ✅* | ✅* |
104
+ | **Embeddings** | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |
105
+ | **Multimodal Prompts** *(text, documents, audio, images, videos, URLs, etc)* | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
106
+ | **Files API** | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
107
+ | **Models API** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
108
+ | **Audio (TTS / Transcribe / Translate)** | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
109
+ | **Image Generation & Editing** | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
110
+ | **Local Model Support** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
111
+ | **Vector Stores (RAG)** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
112
+ | **Responses** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
113
+ | **Moderations** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
106
114
 
107
115
  \* JSON Schema support in Ollama/LlamaCpp depends on the model, not the API.
108
116
 
@@ -141,7 +149,7 @@ llm = LLM.llamacpp(key: nil)
141
149
  The llm.rb library can maintain a process-wide connection pool
142
150
  for each provider that is instantiated. This feature can improve
143
151
  performance but it is optional, the implementation depends on
144
- [net-http-persistent](https://github.com/dbrain/net-http-persistent),
152
+ [net-http-persistent](https://github.com/drbrain/net-http-persistent),
145
153
  and the gem should be installed separately:
146
154
 
147
155
  ```ruby
@@ -684,16 +692,6 @@ else there's the API reference. It covers classes and methods that the README gl
684
692
  over or doesn't cover at all. The API reference is available at
685
693
  [0x1eef.github.io/x/llm.rb](https://0x1eef.github.io/x/llm.rb).
686
694
 
687
- ### Guides
688
-
689
- * [An introduction to RAG](https://0x1eef.github.io/posts/an-introduction-to-rag-with-llm.rb/) &ndash;
690
- a blog post that implements the RAG pattern
691
- * [How to estimate the age of a person in a photo](https://0x1eef.github.io/posts/age-estimation-with-llm.rb/) &ndash;
692
- a blog post that implements an age estimation tool
693
- * [How to edit an image with Gemini](https://0x1eef.github.io/posts/how-to-edit-images-with-gemini/) &ndash;
694
- a blog post that implements image editing with Gemini
695
- * [docs/](docs/) &ndash; the docs directory contains additional guides
696
-
697
695
  ## Install
698
696
 
699
697
  llm.rb can be installed via rubygems.org:
@@ -704,4 +702,4 @@ llm.rb can be installed via rubygems.org:
704
702
 
705
703
  [BSD Zero Clause](https://choosealicense.com/licenses/0bsd/)
706
704
  <br>
707
- See [LICENSE](./LICENSE)
705
+ See [LICENSE](./LICENSE)
data/lib/llm/client.rb CHANGED
@@ -32,6 +32,5 @@ module LLM
32
32
 
33
33
  def client_id = "#{host}:#{port}:#{timeout}:#{ssl}"
34
34
  def clients = self.class.clients
35
- def mutex = self.class.mutex
36
35
  end
37
36
  end
data/lib/llm/provider.rb CHANGED
@@ -87,57 +87,23 @@ class LLM::Provider
87
87
  raise NotImplementedError
88
88
  end
89
89
 
90
- ##
91
- # Starts a new lazy chat powered by the chat completions API
92
- # @note
93
- # This method creates a lazy version of a
94
- # {LLM::Bot LLM::Bot} object.
95
- # @param prompt (see LLM::Provider#complete)
96
- # @param params (see LLM::Provider#complete)
97
- # @return [LLM::Bot]
98
- def chat(prompt, params = {})
99
- role = params.delete(:role)
100
- LLM::Bot.new(self, params).chat(prompt, role:)
101
- end
102
-
103
90
  ##
104
91
  # Starts a new chat powered by the chat completions API
105
- # @note
106
- # This method creates a non-lazy version of a
107
- # {LLM::Bot LLM::Bot} object.
108
92
  # @param prompt (see LLM::Provider#complete)
109
93
  # @param params (see LLM::Provider#complete)
110
- # @raise (see LLM::Provider#complete)
111
94
  # @return [LLM::Bot]
112
- def chat!(prompt, params = {})
95
+ def chat(prompt, params = {})
113
96
  role = params.delete(:role)
114
97
  LLM::Bot.new(self, params).chat(prompt, role:)
115
98
  end
116
99
 
117
- ##
118
- # Starts a new lazy chat powered by the responses API
119
- # @note
120
- # This method creates a lazy variant of a
121
- # {LLM::Bot LLM::Bot} object.
122
- # @param prompt (see LLM::Provider#complete)
123
- # @param params (see LLM::Provider#complete)
124
- # @raise (see LLM::Provider#complete)
125
- # @return [LLM::Bot]
126
- def respond(prompt, params = {})
127
- role = params.delete(:role)
128
- LLM::Bot.new(self, params).respond(prompt, role:)
129
- end
130
-
131
100
  ##
132
101
  # Starts a new chat powered by the responses API
133
- # @note
134
- # This method creates a non-lazy variant of a
135
- # {LLM::Bot LLM::Bot} object.
136
102
  # @param prompt (see LLM::Provider#complete)
137
103
  # @param params (see LLM::Provider#complete)
138
104
  # @raise (see LLM::Provider#complete)
139
105
  # @return [LLM::Bot]
140
- def respond!(prompt, params = {})
106
+ def respond(prompt, params = {})
141
107
  role = params.delete(:role)
142
108
  LLM::Bot.new(self, params).respond(prompt, role:)
143
109
  end
@@ -70,7 +70,7 @@ module LLM
70
70
  role, stream = params.delete(:role), params.delete(:stream)
71
71
  params[:stream] = true if stream.respond_to?(:<<) || stream == true
72
72
  params[:stream_options] = {include_usage: true}.merge!(params[:stream_options] || {}) if params[:stream]
73
- req = Net::HTTP::Post.new("/v1/chat/completions", headers)
73
+ req = Net::HTTP::Post.new(completions_path, headers)
74
74
  messages = [*(params.delete(:messages) || []), Message.new(role, prompt)]
75
75
  body = JSON.dump({messages: format(messages, :complete).flatten}.merge!(params))
76
76
  set_body_stream(req, StringIO.new(body))
@@ -184,6 +184,10 @@ module LLM
184
184
 
185
185
  private
186
186
 
187
+ def completions_path
188
+ "/v1/chat/completions"
189
+ end
190
+
187
191
  def headers
188
192
  (@headers || {}).merge(
189
193
  "Content-Type" => "application/json",
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "openai" unless defined?(LLM::OpenAI)
4
+
5
+ module LLM
6
+ ##
7
+ # The ZAI class implements a provider for [zAI](https://docs.z.ai/guides/overview/quick-start).
8
+ #
9
+ # @example
10
+ # #!/usr/bin/env ruby
11
+ # require "llm"
12
+ #
13
+ # llm = LLM.zai(key: ENV["KEY"])
14
+ # bot = LLM::Bot.new(llm, stream: $stdout)
15
+ # bot.chat("Greetings Robot", role: :user).flush
16
+ class ZAI < OpenAI
17
+ ##
18
+ # @param [String] host A regional host or the default ("api.z.ai")
19
+ # @param key (see LLM::Provider#initialize)
20
+ def initialize(host: "api.z.ai", **)
21
+ super
22
+ end
23
+
24
+ ##
25
+ # @raise [NotImplementedError]
26
+ def files
27
+ raise NotImplementedError
28
+ end
29
+
30
+ ##
31
+ # @return [LLM::XAI::Images]
32
+ def images
33
+ raise NotImplementedError
34
+ end
35
+
36
+ ##
37
+ # @raise [NotImplementedError]
38
+ def audio
39
+ raise NotImplementedError
40
+ end
41
+
42
+ ##
43
+ # @raise [NotImplementedError]
44
+ def moderations
45
+ raise NotImplementedError
46
+ end
47
+
48
+ ##
49
+ # @raise [NotImplementedError]
50
+ def responses
51
+ raise NotImplementedError
52
+ end
53
+
54
+ ##
55
+ # @raise [NotImplementedError]
56
+ def vector_stores
57
+ raise NotImplementedError
58
+ end
59
+
60
+ ##
61
+ # Returns the default model for chat completions
62
+ # #see https://docs.z.ai/guides/llm/glm-4.5#glm-4-5-flash glm-4.5-flash
63
+ # @return [String]
64
+ def default_model
65
+ "glm-4.5-flash"
66
+ end
67
+
68
+ private
69
+
70
+ def completions_path
71
+ "/api/paas/v4/chat/completions"
72
+ end
73
+ end
74
+ end
data/lib/llm/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LLM
4
- VERSION = "0.17.0"
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/llm.rb CHANGED
@@ -23,7 +23,7 @@ module LLM
23
23
 
24
24
  ##
25
25
  # Thread-safe monitors for different contexts
26
- @monitors = { require: Monitor.new, clients: Monitor.new, inherited: Monitor.new }
26
+ @monitors = {require: Monitor.new, clients: Monitor.new, inherited: Monitor.new}
27
27
 
28
28
  module_function
29
29
 
@@ -84,6 +84,15 @@ module LLM
84
84
  LLM::XAI.new(**)
85
85
  end
86
86
 
87
+ ##
88
+ # @param key (see LLM::ZAI#initialize)
89
+ # @param host (see LLM::ZAI#initialize)
90
+ # @return (see LLM::ZAI#initialize)
91
+ def zai(**)
92
+ lock(:require) { require_relative "llm/providers/zai" unless defined?(LLM::ZAI) }
93
+ LLM::ZAI.new(**)
94
+ end
95
+
87
96
  ##
88
97
  # Define a function
89
98
  # @example
data/llm.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
 
11
11
  spec.summary = <<~SUMMARY
12
12
  llm.rb is a zero-dependency Ruby toolkit for Large Language Models that
13
- includes OpenAI, Gemini, Anthropic, xAI (grok), DeepSeek, Ollama, and
13
+ includes OpenAI, Gemini, Anthropic, xAI (grok), zAI, DeepSeek, Ollama, and
14
14
  LlamaCpp. The toolkit includes full support for chat, streaming, tool calling,
15
15
  audio, images, files, and structured outputs (JSON Schema).
16
16
  SUMMARY
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: llm.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antar Azri
@@ -165,7 +165,7 @@ dependencies:
165
165
  - !ruby/object:Gem::Version
166
166
  version: '4.0'
167
167
  description: llm.rb is a zero-dependency Ruby toolkit for Large Language Models that
168
- includes OpenAI, Gemini, Anthropic, xAI (grok), DeepSeek, Ollama, and LlamaCpp.
168
+ includes OpenAI, Gemini, Anthropic, xAI (grok), zAI, DeepSeek, Ollama, and LlamaCpp.
169
169
  The toolkit includes full support for chat, streaming, tool calling, audio, images,
170
170
  files, and structured outputs (JSON Schema).
171
171
  email:
@@ -264,6 +264,7 @@ files:
264
264
  - lib/llm/providers/openai/vector_stores.rb
265
265
  - lib/llm/providers/xai.rb
266
266
  - lib/llm/providers/xai/images.rb
267
+ - lib/llm/providers/zai.rb
267
268
  - lib/llm/response.rb
268
269
  - lib/llm/schema.rb
269
270
  - lib/llm/schema/array.rb
@@ -303,7 +304,7 @@ requirements: []
303
304
  rubygems_version: 3.6.9
304
305
  specification_version: 4
305
306
  summary: llm.rb is a zero-dependency Ruby toolkit for Large Language Models that includes
306
- OpenAI, Gemini, Anthropic, xAI (grok), DeepSeek, Ollama, and LlamaCpp. The toolkit
307
- includes full support for chat, streaming, tool calling, audio, images, files, and
308
- structured outputs (JSON Schema).
307
+ OpenAI, Gemini, Anthropic, xAI (grok), zAI, DeepSeek, Ollama, and LlamaCpp. The
308
+ toolkit includes full support for chat, streaming, tool calling, audio, images,
309
+ files, and structured outputs (JSON Schema).
309
310
  test_files: []