rllama 1.1.0-aarch64-linux-musl → 1.2.0-aarch64-linux-musl

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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +18 -0
  3. data/README.md +100 -8
  4. data/lib/rllama/aarch64-linux-musl/libggml-base.so +1 -0
  5. data/lib/rllama/aarch64-linux-musl/libggml-base.so.0 +1 -0
  6. data/lib/rllama/aarch64-linux-musl/libggml-base.so.0.17.0 +0 -0
  7. data/lib/rllama/aarch64-linux-musl/libggml-cpu.so +1 -0
  8. data/lib/rllama/aarch64-linux-musl/libggml-cpu.so.0 +1 -0
  9. data/lib/rllama/aarch64-linux-musl/libggml-cpu.so.0.17.0 +0 -0
  10. data/lib/rllama/aarch64-linux-musl/libggml.so +1 -0
  11. data/lib/rllama/aarch64-linux-musl/libggml.so.0 +1 -0
  12. data/lib/rllama/aarch64-linux-musl/libggml.so.0.17.0 +0 -0
  13. data/lib/rllama/aarch64-linux-musl/libllama-common.so +1 -0
  14. data/lib/rllama/aarch64-linux-musl/libllama-common.so.0 +1 -0
  15. data/lib/rllama/aarch64-linux-musl/libllama-common.so.0.0.1 +0 -0
  16. data/lib/rllama/aarch64-linux-musl/libllama.so +1 -0
  17. data/lib/rllama/aarch64-linux-musl/libllama.so.0 +1 -0
  18. data/lib/rllama/aarch64-linux-musl/libllama.so.0.0.1 +0 -0
  19. data/lib/rllama/aarch64-linux-musl/libllama_common.so +0 -0
  20. data/lib/rllama/common.rb +134 -0
  21. data/lib/rllama/context.rb +220 -51
  22. data/lib/rllama/cpp.rb +8 -10
  23. data/lib/rllama/model.rb +56 -58
  24. data/lib/rllama/version.rb +1 -1
  25. data/lib/rllama.rb +2 -1
  26. data/licenses/LICENSE-boringssl +238 -0
  27. data/licenses/LICENSE-cpp-httplib +22 -0
  28. data/licenses/LICENSE-json +21 -0
  29. data/licenses/LICENSE-llama.cpp +21 -0
  30. metadata +20 -2
  31. data/lib/rllama/aarch64-linux-musl/libggml-base.so +0 -0
  32. data/lib/rllama/aarch64-linux-musl/libggml-cpu.so +0 -0
  33. data/lib/rllama/aarch64-linux-musl/libggml.so +0 -0
  34. data/lib/rllama/aarch64-linux-musl/libllama.so +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a80d6880748ed5cf8b839e77a56a1d02e7d9e90f0277d7f59ade73a1d028e21d
4
- data.tar.gz: 50a0dc7ba59e4f8c9e0826394565f516775f418f13059a673b923273b4ee08f1
3
+ metadata.gz: a60685cae9784930e34fabf29b018ffe8130d937bf001415dc9ac0eb70b650d2
4
+ data.tar.gz: 836c10cd0f4330ed6201e1be1350e64952d7f44df2a970fa99980f3bced55789
5
5
  SHA512:
6
- metadata.gz: 30bb94f0aafa89cf254fb0cb7ee241bcc33de37c85358a5ce2fb267807647aca75dcfbe99171511c7c5559fa01edb4472eb61f50bb74aef00356cbba5dab7063
7
- data.tar.gz: f1ad99cde067017a96b893b77f491137ebdaf6be793f436721c05511b18699a1ba925cb442b2e669198966df33ede5415b634a6d1ac3235c380c5b694719a4ac
6
+ metadata.gz: 7cc3044bfb13383ffb9c9bad709328d2f175f1e865c20450e71abf53baf25df173dd847f4a64c43bc2935436ad7a87850d0af1e0c057d6adf86c0f97862fc5a8
7
+ data.tar.gz: d90294f8468d7f400034f12dabc3b35a8cc4c9443ebc73b7f0f0975294faa150478ecfd0410f83837370e5f91fddd64feb1a1926db07ff598e7f8a804a6ede76
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DocuSeal, LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
9
+ following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15
+ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
16
+ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -24,12 +24,6 @@ Or install it yourself as:
24
24
  gem install rllama
25
25
  ```
26
26
 
27
- ### Troubleshooting
28
-
29
- #### `llama_model_load_from_file_impl: no backends are loaded`
30
-
31
- If you're running on an Intel (x86_64) CPU and encounter this error while loading a model, make sure you're using the latest version of the gem. Rllama now preloads the bundled GGML backend libraries and automatically augments the `GGML_BACKEND_PATH`, so upgrading resolves the issue without any manual steps. If you build from source, ensure that directory is included in `GGML_BACKEND_PATH` before booting your Ruby process.
32
-
33
27
  ## CLI Chat
34
28
 
35
29
  The `rllama` command-line utility provides an interactive chat interface for conversing with language models. After installing the gem, you can start chatting immediately:
@@ -93,7 +87,14 @@ model.close
93
87
 
94
88
  #### Generation parameters
95
89
 
96
- Adjust the generation with parameters:
90
+ By default the sampling parameters are taken from the model's own
91
+ `general.sampling.*` GGUF metadata when present (falling back to llama.cpp's
92
+ standard defaults: `temperature: 0.8`, `top_k: 40`, `top_p: 0.95`,
93
+ `min_p: 0.05`). You can inspect the resolved values with
94
+ `model.sampling_defaults`, or read any metadata key directly with
95
+ `model.meta('general.sampling.temp')`.
96
+
97
+ Pass any parameter explicitly to override the model default:
97
98
 
98
99
  ```ruby
99
100
  result = model.generate(
@@ -106,6 +107,9 @@ result = model.generate(
106
107
  )
107
108
  ```
108
109
 
110
+ The parameters actually used are reported back in `result.stats`
111
+ (`temperature`, `top_k`, `top_p`, `min_p`, `seed`).
112
+
109
113
  #### Streaming generation
110
114
 
111
115
  Stream generated text token-by-token:
@@ -141,6 +145,95 @@ result = model.generate([
141
145
  puts result.text
142
146
  ```
143
147
 
148
+ #### Tool definitions
149
+
150
+ Pass tool definitions to include them in the model's prompt for function calling:
151
+
152
+ ```ruby
153
+ tools = [
154
+ {
155
+ type: 'function',
156
+ function: {
157
+ name: 'get_weather',
158
+ description: 'Get the current weather for a location',
159
+ parameters: {
160
+ type: 'object',
161
+ properties: {
162
+ location: { type: 'string', description: 'City name' }
163
+ },
164
+ required: ['location']
165
+ }
166
+ }
167
+ }
168
+ ]
169
+
170
+ result = model.generate('What is the weather in Paris?', tools:)
171
+ puts result.text
172
+ ```
173
+
174
+ #### Tool call results
175
+
176
+ Messages are passed to the model's chat template in the OpenAI format, so tool
177
+ calls and their results are wired through the standard message schema: the
178
+ assistant message carries a structured `tool_calls:` array, and the tool output
179
+ is sent back as a `role: 'tool'` message.
180
+
181
+ Pass `tools:` (and optionally `system:`) once when creating the context — they
182
+ are remembered for all subsequent turns. When the model emits a tool call, it
183
+ is parsed into `result.tool_calls` and stored in the conversation history in
184
+ structured form automatically. Execute the calls and send each result back as
185
+ a `role: 'tool'` message:
186
+
187
+ ```ruby
188
+ context = model.init_context(tools:)
189
+
190
+ result = context.generate('What is the weather in Paris?')
191
+ result.tool_calls
192
+ # => [{ name: 'get_weather', arguments: { 'location' => 'Paris' }, id: 'call_1' }]
193
+
194
+ result.tool_calls.each do |call|
195
+ weather = get_weather(call[:arguments]['location'])
196
+
197
+ result = context.generate(
198
+ { role: 'tool', tool_call_id: call[:id], name: call[:name], content: weather.to_json }
199
+ )
200
+ end
201
+
202
+ puts result.text
203
+ # => "The weather in Paris right now is 21°C."
204
+ ```
205
+
206
+ The tool call markup is parsed by llama.cpp's chat parser, which derives the
207
+ format automatically from the model's own chat template — any model with a
208
+ tool-capable template is supported. If no tool call is detected,
209
+ `result.tool_calls` is empty and `result.text` contains the raw output.
210
+
211
+ The context detects the edited history and automatically rolls the KV cache
212
+ back to the common prefix, so only the changed suffix is re-processed.
213
+
214
+ ### Reasoning
215
+
216
+ For models with reasoning support, pass `reasoning: true` to
217
+ enable the model's reasoning phase. The reasoning block is parsed out of the
218
+ output: `result.text` contains only the final answer and the reasoning is
219
+ available separately:
220
+
221
+ ```ruby
222
+ result = model.generate('Why is the sky blue?', reasoning: true)
223
+
224
+ result.reasoning
225
+ # => "Thinking Process:\n\n1. Analyze the request..."
226
+
227
+ result.text
228
+ # => "The sky appears blue because..."
229
+ ```
230
+
231
+ Like `tools:`, the flag can also be set once per context via
232
+ `model.init_context(reasoning: true)`. It defaults to off; `result.reasoning`
233
+ is `nil` when reasoning is disabled or the model produced no reasoning block.
234
+ Note that when streaming with a block, the raw reasoning tokens are yielded
235
+ as they are generated.
236
+
144
237
  ### Chat
145
238
 
146
239
  For ongoing conversations, use a context object that maintains the conversation history:
@@ -213,7 +306,6 @@ You can download GGUF format models from various sources:
213
306
 
214
307
  - [Hugging Face](https://huggingface.co/models?library=gguf) - Search for models with "GGUF" format
215
308
 
216
-
217
309
  ## License
218
310
 
219
311
  MIT
@@ -0,0 +1 @@
1
+ libggml-base.so.0
@@ -0,0 +1 @@
1
+ libggml-base.so.0.17.0
@@ -0,0 +1 @@
1
+ libggml-cpu.so.0
@@ -0,0 +1 @@
1
+ libggml-cpu.so.0.17.0
@@ -0,0 +1 @@
1
+ libggml.so.0
@@ -0,0 +1 @@
1
+ libggml.so.0.17.0
@@ -0,0 +1 @@
1
+ libllama-common.so.0
@@ -0,0 +1 @@
1
+ libllama-common.so.0.0.1
@@ -0,0 +1 @@
1
+ libllama.so.0
@@ -0,0 +1 @@
1
+ libllama.so.0.0.1
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ require 'json'
5
+
6
+ module Rllama
7
+ module Common
8
+ extend FFI::Library
9
+
10
+ REASONING_FORMAT_AUTO = 1
11
+
12
+ lib_file =
13
+ case FFI::Platform::OS
14
+ when 'darwin'
15
+ 'libllama_common.dylib'
16
+ when 'windows', 'mingw32'
17
+ 'llama_common.dll'
18
+ else
19
+ 'libllama_common.so'
20
+ end
21
+
22
+ ffi_lib File.join(Cpp::PLATFORM_DIR, lib_file)
23
+
24
+ attach_function :rlc_free, [:pointer], :void
25
+ attach_function :rlc_chat_templates_init, %i[pointer string string string pointer], :pointer
26
+ attach_function :rlc_chat_templates_free, [:pointer], :void
27
+ attach_function :rlc_chat_apply, %i[pointer string pointer], :pointer
28
+ attach_function :rlc_chat_parse, %i[string bool string pointer], :pointer
29
+ attach_function :rlc_sampler_init, %i[pointer string pointer], :pointer
30
+ attach_function :rlc_sampler_free, [:pointer], :void
31
+ attach_function :rlc_sampler_sample, %i[pointer pointer int32], :int32
32
+ attach_function :rlc_sampler_accept, %i[pointer int32 bool], :void
33
+ attach_function :rlc_sampler_reset, [:pointer], :void
34
+ attach_function :rlc_sampler_print, [:pointer], :pointer
35
+
36
+ module_function
37
+
38
+ def chat_templates_init(model, source, bos_token, eos_token)
39
+ with_err do |err|
40
+ handle = rlc_chat_templates_init(model, source, bos_token, eos_token, err)
41
+
42
+ raise Error, "Failed to parse chat template: #{read_err(err)}" if handle.null?
43
+
44
+ handle
45
+ end
46
+ end
47
+
48
+ def chat_templates_free(handle)
49
+ rlc_chat_templates_free(handle)
50
+ end
51
+
52
+ def chat_apply(handle, messages:, tools: nil, add_generation_prompt: true, enable_thinking: false,
53
+ add_bos: false, add_eos: false)
54
+ inputs = { messages:, tools:, add_generation_prompt:, enable_thinking:, add_bos:, add_eos:,
55
+ reasoning_format: enable_thinking ? REASONING_FORMAT_AUTO : 0 }.to_json
56
+
57
+ with_err do |err|
58
+ result = rlc_chat_apply(handle, inputs, err)
59
+
60
+ raise Error, "Failed to apply chat template: #{read_err(err)}" if result.null?
61
+
62
+ JSON.parse(take(result))
63
+ end
64
+ end
65
+
66
+ def chat_parse(text, params, is_partial: false, reasoning: false)
67
+ parse_params = params.slice('format', 'parser', 'generation_prompt')
68
+ parse_params['reasoning_format'] = REASONING_FORMAT_AUTO if reasoning
69
+ params_json = parse_params.to_json
70
+
71
+ with_err do |err|
72
+ result = rlc_chat_parse(text, is_partial, params_json, err)
73
+
74
+ raise Error, "Failed to parse output: #{read_err(err)}" if result.null?
75
+
76
+ JSON.parse(take(result))
77
+ end
78
+ end
79
+
80
+ def sampler_init(model, params)
81
+ with_err do |err|
82
+ handle = rlc_sampler_init(model, params.to_json, err)
83
+
84
+ raise Error, "Failed to initialize sampler: #{read_err(err)}" if handle.null?
85
+
86
+ handle
87
+ end
88
+ end
89
+
90
+ def sampler_free(handle)
91
+ rlc_sampler_free(handle)
92
+ end
93
+
94
+ def sampler_sample(handle, ctx, idx = -1)
95
+ rlc_sampler_sample(handle, ctx, idx)
96
+ end
97
+
98
+ def sampler_accept(handle, token, accept_grammar: true)
99
+ rlc_sampler_accept(handle, token, accept_grammar)
100
+ end
101
+
102
+ def sampler_reset(handle)
103
+ rlc_sampler_reset(handle)
104
+ end
105
+
106
+ def sampler_print(handle)
107
+ take(rlc_sampler_print(handle))
108
+ end
109
+
110
+ def with_err
111
+ yield FFI::MemoryPointer.new(:pointer)
112
+ end
113
+
114
+ def take(ptr)
115
+ str = ptr.read_string
116
+
117
+ rlc_free(ptr)
118
+
119
+ str
120
+ end
121
+
122
+ def read_err(err)
123
+ msg_ptr = err.read_pointer
124
+
125
+ return 'unknown error' if msg_ptr.null?
126
+
127
+ msg = msg_ptr.read_string
128
+
129
+ rlc_free(msg_ptr)
130
+
131
+ msg
132
+ end
133
+ end
134
+ end