ruby_llm 1.9.2 → 1.10.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/README.md +3 -2
- data/lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt +3 -0
- data/lib/generators/ruby_llm/install/templates/create_tool_calls_migration.rb.tt +1 -0
- data/lib/generators/ruby_llm/upgrade_to_v1_10/templates/add_v1_10_message_columns.rb.tt +19 -0
- data/lib/generators/ruby_llm/upgrade_to_v1_10/upgrade_to_v1_10_generator.rb +50 -0
- data/lib/ruby_llm/active_record/acts_as_legacy.rb +5 -1
- data/lib/ruby_llm/active_record/chat_methods.rb +12 -0
- data/lib/ruby_llm/active_record/message_methods.rb +41 -8
- data/lib/ruby_llm/aliases.json +0 -12
- data/lib/ruby_llm/chat.rb +10 -7
- data/lib/ruby_llm/configuration.rb +1 -1
- data/lib/ruby_llm/message.rb +37 -11
- data/lib/ruby_llm/models.json +1059 -857
- data/lib/ruby_llm/models.rb +134 -12
- data/lib/ruby_llm/provider.rb +4 -3
- data/lib/ruby_llm/providers/anthropic/chat.rb +128 -13
- data/lib/ruby_llm/providers/anthropic/streaming.rb +25 -1
- data/lib/ruby_llm/providers/bedrock/chat.rb +58 -15
- data/lib/ruby_llm/providers/bedrock/streaming/content_extraction.rb +59 -2
- data/lib/ruby_llm/providers/bedrock/streaming/payload_processing.rb +5 -0
- data/lib/ruby_llm/providers/gemini/chat.rb +69 -3
- data/lib/ruby_llm/providers/gemini/streaming.rb +32 -1
- data/lib/ruby_llm/providers/gemini/tools.rb +16 -3
- data/lib/ruby_llm/providers/gpustack/chat.rb +1 -1
- data/lib/ruby_llm/providers/mistral/chat.rb +58 -1
- data/lib/ruby_llm/providers/ollama/chat.rb +1 -1
- data/lib/ruby_llm/providers/openai/capabilities.rb +6 -2
- data/lib/ruby_llm/providers/openai/chat.rb +87 -3
- data/lib/ruby_llm/providers/openai/streaming.rb +11 -3
- data/lib/ruby_llm/providers/openai/temperature.rb +28 -0
- data/lib/ruby_llm/providers/openai.rb +1 -1
- data/lib/ruby_llm/providers/openrouter/chat.rb +154 -0
- data/lib/ruby_llm/providers/openrouter/streaming.rb +74 -0
- data/lib/ruby_llm/providers/openrouter.rb +2 -0
- data/lib/ruby_llm/providers/vertexai.rb +5 -1
- data/lib/ruby_llm/stream_accumulator.rb +111 -14
- data/lib/ruby_llm/streaming.rb +54 -51
- data/lib/ruby_llm/thinking.rb +49 -0
- data/lib/ruby_llm/tokens.rb +47 -0
- data/lib/ruby_llm/tool_call.rb +6 -3
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/tasks/models.rake +19 -12
- metadata +12 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5c88c057a541d5c27c5ab61a9bcf6db9e20c702fdb34b5b26d2d3154128f8dbd
|
|
4
|
+
data.tar.gz: d425e78899c69aa798838f0f3bf6e6f99f3e3ddc9c9057ded3bd7360b482acd1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4545a9ef9254ec489924172c3f82fec9fd59986517e61b0e6ab24465dd5e4cd44f35296f14da3e3416c71bea05a1147ac80bf206fde68e071ae525c5e6effd27
|
|
7
|
+
data.tar.gz: 9be86b4db70aba3d4684dc81bac6949895c9232a0783f3b1f13758356565de682c4d8b9a1ff1aac70ceedcde9fd363b0a5b4e941516d26aafbc783d0e7692dd2
|
data/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<strong>One *beautiful* Ruby API for GPT, Claude, Gemini, and more.</strong>
|
|
9
9
|
|
|
10
|
-
Battle tested at [<picture><source media="(prefers-color-scheme: dark)" srcset="https://chatwithwork.com/logotype-dark.svg"><img src="https://chatwithwork.com/logotype.svg" alt="Chat with Work" height="30" align="absmiddle"></picture>](https://chatwithwork.com) — *
|
|
10
|
+
Battle tested at [<picture><source media="(prefers-color-scheme: dark)" srcset="https://chatwithwork.com/logotype-dark.svg"><img src="https://chatwithwork.com/logotype.svg" alt="Chat with Work" height="30" align="absmiddle"></picture>](https://chatwithwork.com) — *Your AI coworker*
|
|
11
11
|
|
|
12
12
|
[](https://badge.fury.io/rb/ruby_llm)
|
|
13
13
|
[](https://github.com/rubocop/rubocop)
|
|
@@ -122,7 +122,8 @@ response = chat.with_schema(ProductSchema).ask "Analyze this product", with: "pr
|
|
|
122
122
|
* **Streaming:** Real-time responses with blocks
|
|
123
123
|
* **Rails:** ActiveRecord integration with `acts_as_chat`
|
|
124
124
|
* **Async:** Fiber-based concurrency
|
|
125
|
-
* **Model registry:**
|
|
125
|
+
* **Model registry:** 800+ models with capability detection and pricing
|
|
126
|
+
* **Extended thinking:** Control, view, and persist model deliberation
|
|
126
127
|
* **Providers:** OpenAI, Anthropic, Gemini, VertexAI, Bedrock, DeepSeek, Mistral, Ollama, OpenRouter, Perplexity, GPUStack, and any OpenAI-compatible API
|
|
127
128
|
|
|
128
129
|
## Installation
|
|
@@ -4,6 +4,9 @@ class Create<%= message_model_name.gsub('::', '').pluralize %> < ActiveRecord::M
|
|
|
4
4
|
t.string :role, null: false
|
|
5
5
|
t.text :content
|
|
6
6
|
t.json :content_raw
|
|
7
|
+
t.text :thinking_text
|
|
8
|
+
t.text :thinking_signature
|
|
9
|
+
t.integer :thinking_tokens
|
|
7
10
|
t.integer :input_tokens
|
|
8
11
|
t.integer :output_tokens
|
|
9
12
|
t.integer :cached_tokens
|
|
@@ -4,6 +4,7 @@ class Create<%= tool_call_model_name.gsub('::', '').pluralize %> < ActiveRecord:
|
|
|
4
4
|
create_table :<%= tool_call_table_name %> do |t|
|
|
5
5
|
t.string :tool_call_id, null: false
|
|
6
6
|
t.string :name, null: false
|
|
7
|
+
t.string :thought_signature
|
|
7
8
|
<% if postgresql? %>
|
|
8
9
|
t.jsonb :arguments, default: {}
|
|
9
10
|
<% elsif mysql? %>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class AddRubyLlmV110Columns < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def change
|
|
3
|
+
unless column_exists?(:<%= message_table_name %>, :thinking_text)
|
|
4
|
+
add_column :<%= message_table_name %>, :thinking_text, :text
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
unless column_exists?(:<%= message_table_name %>, :thinking_signature)
|
|
8
|
+
add_column :<%= message_table_name %>, :thinking_signature, :text
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
unless column_exists?(:<%= message_table_name %>, :thinking_tokens)
|
|
12
|
+
add_column :<%= message_table_name %>, :thinking_tokens, :integer
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
unless column_exists?(:<%= tool_call_table_name %>, :thought_signature)
|
|
16
|
+
add_column :<%= tool_call_table_name %>, :thought_signature, :string
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails/generators'
|
|
4
|
+
require 'rails/generators/active_record'
|
|
5
|
+
require_relative '../generator_helpers'
|
|
6
|
+
|
|
7
|
+
module RubyLLM
|
|
8
|
+
module Generators
|
|
9
|
+
# Generator to add v1.10 columns (thinking output + thinking tokens) to existing apps.
|
|
10
|
+
class UpgradeToV110Generator < Rails::Generators::Base
|
|
11
|
+
include Rails::Generators::Migration
|
|
12
|
+
include RubyLLM::Generators::GeneratorHelpers
|
|
13
|
+
|
|
14
|
+
namespace 'ruby_llm:upgrade_to_v1_10'
|
|
15
|
+
source_root File.expand_path('templates', __dir__)
|
|
16
|
+
|
|
17
|
+
argument :model_mappings, type: :array, default: [], banner: 'message:MessageName'
|
|
18
|
+
|
|
19
|
+
desc 'Adds thinking output columns and thinking token tracking introduced in v1.10.0'
|
|
20
|
+
|
|
21
|
+
def self.next_migration_number(dirname)
|
|
22
|
+
::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def create_migration_file
|
|
26
|
+
parse_model_mappings
|
|
27
|
+
|
|
28
|
+
migration_template 'add_v1_10_message_columns.rb.tt',
|
|
29
|
+
'db/migrate/add_ruby_llm_v1_10_columns.rb',
|
|
30
|
+
migration_version: migration_version,
|
|
31
|
+
message_table_name: message_table_name,
|
|
32
|
+
tool_call_table_name: tool_call_table_name
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def show_next_steps
|
|
36
|
+
say_status :success, 'Upgrade prepared!', :green
|
|
37
|
+
say <<~INSTRUCTIONS
|
|
38
|
+
|
|
39
|
+
Next steps:
|
|
40
|
+
1. Review the generated migration
|
|
41
|
+
2. Run: rails db:migrate
|
|
42
|
+
3. Restart your application server
|
|
43
|
+
|
|
44
|
+
📚 See the v1.10.0 release notes for details on extended thinking support.
|
|
45
|
+
|
|
46
|
+
INSTRUCTIONS
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -279,8 +279,11 @@ module RubyLLM
|
|
|
279
279
|
end
|
|
280
280
|
|
|
281
281
|
def persist_tool_calls(tool_calls)
|
|
282
|
+
supports_thought_signature = tool_calls.klass.column_names.include?('thought_signature')
|
|
283
|
+
|
|
282
284
|
tool_calls.each_value do |tool_call|
|
|
283
285
|
attributes = tool_call.to_h
|
|
286
|
+
attributes.delete(:thought_signature) unless supports_thought_signature
|
|
284
287
|
attributes[:tool_call_id] = attributes.delete(:id)
|
|
285
288
|
@message.tool_calls.create!(**attributes)
|
|
286
289
|
end
|
|
@@ -357,7 +360,8 @@ module RubyLLM
|
|
|
357
360
|
RubyLLM::ToolCall.new(
|
|
358
361
|
id: tool_call.tool_call_id,
|
|
359
362
|
name: tool_call.name,
|
|
360
|
-
arguments: tool_call.arguments
|
|
363
|
+
arguments: tool_call.arguments,
|
|
364
|
+
thought_signature: tool_call.try(:thought_signature)
|
|
361
365
|
)
|
|
362
366
|
]
|
|
363
367
|
end
|
|
@@ -124,6 +124,11 @@ module RubyLLM
|
|
|
124
124
|
self
|
|
125
125
|
end
|
|
126
126
|
|
|
127
|
+
def with_thinking(...)
|
|
128
|
+
to_llm.with_thinking(...)
|
|
129
|
+
self
|
|
130
|
+
end
|
|
131
|
+
|
|
127
132
|
def with_params(...)
|
|
128
133
|
to_llm.with_params(...)
|
|
129
134
|
self
|
|
@@ -262,6 +267,9 @@ module RubyLLM
|
|
|
262
267
|
if @message.has_attribute?(:cache_creation_tokens)
|
|
263
268
|
attrs[:cache_creation_tokens] = message.cache_creation_tokens
|
|
264
269
|
end
|
|
270
|
+
attrs[:thinking_text] = message.thinking&.text if @message.has_attribute?(:thinking_text)
|
|
271
|
+
attrs[:thinking_signature] = message.thinking&.signature if @message.has_attribute?(:thinking_signature)
|
|
272
|
+
attrs[:thinking_tokens] = message.thinking_tokens if @message.has_attribute?(:thinking_tokens)
|
|
265
273
|
|
|
266
274
|
# Add model association dynamically
|
|
267
275
|
attrs[self.class.model_association_name] = model_association
|
|
@@ -282,8 +290,12 @@ module RubyLLM
|
|
|
282
290
|
# rubocop:enable Metrics/PerceivedComplexity
|
|
283
291
|
|
|
284
292
|
def persist_tool_calls(tool_calls)
|
|
293
|
+
tool_call_klass = @message.tool_calls_association.klass
|
|
294
|
+
supports_thought_signature = tool_call_klass.column_names.include?('thought_signature')
|
|
295
|
+
|
|
285
296
|
tool_calls.each_value do |tool_call|
|
|
286
297
|
attributes = tool_call.to_h
|
|
298
|
+
attributes.delete(:thought_signature) unless supports_thought_signature
|
|
287
299
|
attributes[:tool_call_id] = attributes.delete(:id)
|
|
288
300
|
@message.tool_calls_association.create!(**attributes)
|
|
289
301
|
end
|
|
@@ -11,24 +11,56 @@ module RubyLLM
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def to_llm
|
|
14
|
-
cached = has_attribute?(:cached_tokens) ? self[:cached_tokens] : nil
|
|
15
|
-
cache_creation = has_attribute?(:cache_creation_tokens) ? self[:cache_creation_tokens] : nil
|
|
16
|
-
|
|
17
14
|
RubyLLM::Message.new(
|
|
18
15
|
role: role.to_sym,
|
|
19
16
|
content: extract_content,
|
|
17
|
+
thinking: thinking,
|
|
18
|
+
tokens: tokens,
|
|
20
19
|
tool_calls: extract_tool_calls,
|
|
21
20
|
tool_call_id: extract_tool_call_id,
|
|
22
|
-
input_tokens: input_tokens,
|
|
23
|
-
output_tokens: output_tokens,
|
|
24
|
-
cached_tokens: cached,
|
|
25
|
-
cache_creation_tokens: cache_creation,
|
|
26
21
|
model_id: model_association&.model_id
|
|
27
22
|
)
|
|
28
23
|
end
|
|
29
24
|
|
|
25
|
+
def thinking
|
|
26
|
+
RubyLLM::Thinking.build(
|
|
27
|
+
text: thinking_text_value,
|
|
28
|
+
signature: thinking_signature_value
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def tokens
|
|
33
|
+
RubyLLM::Tokens.build(
|
|
34
|
+
input: input_tokens,
|
|
35
|
+
output: output_tokens,
|
|
36
|
+
cached: cached_value,
|
|
37
|
+
cache_creation: cache_creation_value,
|
|
38
|
+
thinking: thinking_tokens_value
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
|
|
30
42
|
private
|
|
31
43
|
|
|
44
|
+
def thinking_text_value
|
|
45
|
+
has_attribute?(:thinking_text) ? self[:thinking_text] : nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def thinking_signature_value
|
|
49
|
+
has_attribute?(:thinking_signature) ? self[:thinking_signature] : nil
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def cached_value
|
|
53
|
+
has_attribute?(:cached_tokens) ? self[:cached_tokens] : nil
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def cache_creation_value
|
|
57
|
+
has_attribute?(:cache_creation_tokens) ? self[:cache_creation_tokens] : nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def thinking_tokens_value
|
|
61
|
+
has_attribute?(:thinking_tokens) ? self[:thinking_tokens] : nil
|
|
62
|
+
end
|
|
63
|
+
|
|
32
64
|
def extract_tool_calls
|
|
33
65
|
tool_calls_association.to_h do |tool_call|
|
|
34
66
|
[
|
|
@@ -36,7 +68,8 @@ module RubyLLM
|
|
|
36
68
|
RubyLLM::ToolCall.new(
|
|
37
69
|
id: tool_call.tool_call_id,
|
|
38
70
|
name: tool_call.name,
|
|
39
|
-
arguments: tool_call.arguments
|
|
71
|
+
arguments: tool_call.arguments,
|
|
72
|
+
thought_signature: tool_call.try(:thought_signature)
|
|
40
73
|
)
|
|
41
74
|
]
|
|
42
75
|
end
|
data/lib/ruby_llm/aliases.json
CHANGED
|
@@ -336,18 +336,6 @@
|
|
|
336
336
|
"openai": "gpt-5.2-pro",
|
|
337
337
|
"openrouter": "openai/gpt-5.2-pro"
|
|
338
338
|
},
|
|
339
|
-
"imagen-4.0-fast-generate-001": {
|
|
340
|
-
"gemini": "imagen-4.0-fast-generate-001",
|
|
341
|
-
"vertexai": "imagen-4.0-fast-generate-001"
|
|
342
|
-
},
|
|
343
|
-
"imagen-4.0-generate-001": {
|
|
344
|
-
"gemini": "imagen-4.0-generate-001",
|
|
345
|
-
"vertexai": "imagen-4.0-generate-001"
|
|
346
|
-
},
|
|
347
|
-
"imagen-4.0-ultra-generate-001": {
|
|
348
|
-
"gemini": "imagen-4.0-ultra-generate-001",
|
|
349
|
-
"vertexai": "imagen-4.0-ultra-generate-001"
|
|
350
|
-
},
|
|
351
339
|
"o1": {
|
|
352
340
|
"openai": "o1",
|
|
353
341
|
"openrouter": "openai/o1"
|
data/lib/ruby_llm/chat.rb
CHANGED
|
@@ -22,6 +22,7 @@ module RubyLLM
|
|
|
22
22
|
@params = {}
|
|
23
23
|
@headers = {}
|
|
24
24
|
@schema = nil
|
|
25
|
+
@thinking = nil
|
|
25
26
|
@on = {
|
|
26
27
|
new_message: nil,
|
|
27
28
|
end_message: nil,
|
|
@@ -67,6 +68,13 @@ module RubyLLM
|
|
|
67
68
|
self
|
|
68
69
|
end
|
|
69
70
|
|
|
71
|
+
def with_thinking(effort: nil, budget: nil)
|
|
72
|
+
raise ArgumentError, 'with_thinking requires :effort or :budget' if effort.nil? && budget.nil?
|
|
73
|
+
|
|
74
|
+
@thinking = Thinking::Config.new(effort: effort, budget: budget)
|
|
75
|
+
self
|
|
76
|
+
end
|
|
77
|
+
|
|
70
78
|
def with_context(context)
|
|
71
79
|
@context = context
|
|
72
80
|
@config = context.config
|
|
@@ -130,6 +138,7 @@ module RubyLLM
|
|
|
130
138
|
params: @params,
|
|
131
139
|
headers: @headers,
|
|
132
140
|
schema: @schema,
|
|
141
|
+
thinking: @thinking,
|
|
133
142
|
&wrap_streaming_block(&)
|
|
134
143
|
)
|
|
135
144
|
|
|
@@ -172,15 +181,9 @@ module RubyLLM
|
|
|
172
181
|
def wrap_streaming_block(&block)
|
|
173
182
|
return nil unless block_given?
|
|
174
183
|
|
|
175
|
-
|
|
184
|
+
@on[:new_message]&.call
|
|
176
185
|
|
|
177
186
|
proc do |chunk|
|
|
178
|
-
# Create message on first content chunk
|
|
179
|
-
unless first_chunk_received
|
|
180
|
-
first_chunk_received = true
|
|
181
|
-
@on[:new_message]&.call
|
|
182
|
-
end
|
|
183
|
-
|
|
184
187
|
block.call chunk
|
|
185
188
|
end
|
|
186
189
|
end
|
|
@@ -56,7 +56,7 @@ module RubyLLM
|
|
|
56
56
|
@retry_interval_randomness = 0.5
|
|
57
57
|
@http_proxy = nil
|
|
58
58
|
|
|
59
|
-
@default_model = 'gpt-
|
|
59
|
+
@default_model = 'gpt-5-nano'
|
|
60
60
|
@default_embedding_model = 'text-embedding-3-small'
|
|
61
61
|
@default_moderation_model = 'omni-moderation-latest'
|
|
62
62
|
@default_image_model = 'gpt-image-1'
|
data/lib/ruby_llm/message.rb
CHANGED
|
@@ -5,8 +5,7 @@ module RubyLLM
|
|
|
5
5
|
class Message
|
|
6
6
|
ROLES = %i[system user assistant tool].freeze
|
|
7
7
|
|
|
8
|
-
attr_reader :role, :model_id, :tool_calls, :tool_call_id, :
|
|
9
|
-
:cached_tokens, :cache_creation_tokens, :raw
|
|
8
|
+
attr_reader :role, :model_id, :tool_calls, :tool_call_id, :raw, :thinking, :tokens
|
|
10
9
|
attr_writer :content
|
|
11
10
|
|
|
12
11
|
def initialize(options = {})
|
|
@@ -15,11 +14,16 @@ module RubyLLM
|
|
|
15
14
|
@model_id = options[:model_id]
|
|
16
15
|
@tool_calls = options[:tool_calls]
|
|
17
16
|
@tool_call_id = options[:tool_call_id]
|
|
18
|
-
@
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
@tokens = options[:tokens] || Tokens.build(
|
|
18
|
+
input: options[:input_tokens],
|
|
19
|
+
output: options[:output_tokens],
|
|
20
|
+
cached: options[:cached_tokens],
|
|
21
|
+
cache_creation: options[:cache_creation_tokens],
|
|
22
|
+
thinking: options[:thinking_tokens],
|
|
23
|
+
reasoning: options[:reasoning_tokens]
|
|
24
|
+
)
|
|
22
25
|
@raw = options[:raw]
|
|
26
|
+
@thinking = options[:thinking]
|
|
23
27
|
|
|
24
28
|
ensure_valid_role
|
|
25
29
|
end
|
|
@@ -44,6 +48,30 @@ module RubyLLM
|
|
|
44
48
|
content if tool_result?
|
|
45
49
|
end
|
|
46
50
|
|
|
51
|
+
def input_tokens
|
|
52
|
+
tokens&.input
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def output_tokens
|
|
56
|
+
tokens&.output
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def cached_tokens
|
|
60
|
+
tokens&.cached
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def cache_creation_tokens
|
|
64
|
+
tokens&.cache_creation
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def thinking_tokens
|
|
68
|
+
tokens&.thinking
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def reasoning_tokens
|
|
72
|
+
tokens&.thinking
|
|
73
|
+
end
|
|
74
|
+
|
|
47
75
|
def to_h
|
|
48
76
|
{
|
|
49
77
|
role: role,
|
|
@@ -51,11 +79,9 @@ module RubyLLM
|
|
|
51
79
|
model_id: model_id,
|
|
52
80
|
tool_calls: tool_calls,
|
|
53
81
|
tool_call_id: tool_call_id,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
cache_creation_tokens: cache_creation_tokens
|
|
58
|
-
}.compact
|
|
82
|
+
thinking: thinking&.text,
|
|
83
|
+
thinking_signature: thinking&.signature
|
|
84
|
+
}.merge(tokens ? tokens.to_h : {}).compact
|
|
59
85
|
end
|
|
60
86
|
|
|
61
87
|
def instance_variables
|