llm.rb 0.17.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 +4 -4
- data/README.md +29 -31
- data/lib/llm/client.rb +0 -1
- data/lib/llm/provider.rb +2 -36
- data/lib/llm/providers/openai/response/completion.rb +4 -3
- data/lib/llm/providers/openai/response/enumerable.rb +12 -0
- data/lib/llm/providers/openai.rb +5 -1
- data/lib/llm/providers/zai.rb +74 -0
- data/lib/llm/version.rb +1 -1
- data/lib/llm.rb +10 -1
- data/llm.gemspec +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 207a44401195a654a57ebf8050d211fc2c1722420a647dedcc447031aead1451
|
4
|
+
data.tar.gz: aa8abf7d5104d0a93033a43041057d1af96f8f45dde7f924243788cd0b14621e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8faf81ef91911ecbcd81694232f6e314caed8dab2ca8b30a241d8e346c3a4a084f0d46bb9e5e94f191a3dc7676c1c865f7062d440498d94e2e0b30a57a5a3510
|
7
|
+
data.tar.gz: 3ba71c5c46b5ebbec12d136f24cff08d0da11ea807b81db1319c31b1dae18cb6786ad8ed759f3333d7e2f0f1ee3c69ee7ae85cf95e6d82b3e5552f0d516a279e
|
data/README.md
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
> **⚠️ Maintenance Mode ⚠️** <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 are 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),
|
5
|
-
LlamaCpp. The toolkit includes full support for chat, streaming,
|
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/) –
|
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/) –
|
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/
|
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/) –
|
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/) –
|
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/) –
|
694
|
-
a blog post that implements image editing with Gemini
|
695
|
-
* [docs/](docs/) – 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
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
|
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
|
106
|
+
def respond(prompt, params = {})
|
141
107
|
role = params.delete(:role)
|
142
108
|
LLM::Bot.new(self, params).respond(prompt, role:)
|
143
109
|
end
|
@@ -18,9 +18,10 @@ module LLM::OpenAI::Response
|
|
18
18
|
alias_method :messages, :choices
|
19
19
|
|
20
20
|
def model = body.model
|
21
|
-
def prompt_tokens =
|
22
|
-
def completion_tokens =
|
23
|
-
def total_tokens =
|
21
|
+
def prompt_tokens = usage["prompt_tokens"]
|
22
|
+
def completion_tokens = usage["completion_tokens"]
|
23
|
+
def total_tokens = usage["total_tokens"]
|
24
|
+
def usage = body.usage || {}
|
24
25
|
|
25
26
|
private
|
26
27
|
|
@@ -7,5 +7,17 @@ module LLM::OpenAI::Response
|
|
7
7
|
return enum_for(:each) unless block_given?
|
8
8
|
data.each { yield(_1) }
|
9
9
|
end
|
10
|
+
|
11
|
+
##
|
12
|
+
# @return [Boolean]
|
13
|
+
def empty?
|
14
|
+
data.empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# @return [Integer]
|
19
|
+
def size
|
20
|
+
data.size
|
21
|
+
end
|
10
22
|
end
|
11
23
|
end
|
data/lib/llm/providers/openai.rb
CHANGED
@@ -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(
|
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
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 = {
|
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.
|
4
|
+
version: 1.0.1
|
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
|
307
|
-
includes full support for chat, streaming, tool calling, audio, images,
|
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: []
|