ruby_llm 2.0.0.rc1 → 2.0.0.rc3
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 +2 -2
- data/lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt +0 -2
- data/lib/generators/ruby_llm/provider/templates/gem/gemfile.erb +1 -3
- data/lib/generators/ruby_llm/provider/templates/gem/gemspec.erb +1 -1
- data/lib/generators/ruby_llm/upgrade/legacy_content_sql.rb +34 -0
- data/lib/generators/ruby_llm/upgrade/online_copy_migration/data.rb +332 -0
- data/lib/generators/ruby_llm/upgrade/online_copy_migration/journal.rb +171 -0
- data/lib/generators/ruby_llm/upgrade/online_copy_migration/verification.rb +197 -0
- data/lib/generators/ruby_llm/upgrade/online_copy_migration.rb +170 -0
- data/lib/generators/ruby_llm/upgrade/templates/backfill_v2_data.rb.tt +14 -11
- data/lib/generators/ruby_llm/upgrade/templates/cleanup_v2_upgrade.rb.tt +7 -6
- data/lib/generators/ruby_llm/upgrade/templates/finish_v2_upgrade.rb.tt +31 -5
- data/lib/generators/ruby_llm/upgrade/templates/prepare_v2_upgrade.rb.tt +16 -14
- data/lib/generators/ruby_llm/upgrade/templates/ruby_llm_upgrade.rb.tt +36 -7
- data/lib/generators/ruby_llm/upgrade/upgrade_generator.rb +15 -5
- data/lib/generators/ruby_llm/upgrade/upgrade_migration.rb +14 -0
- data/lib/ruby_llm/accounting/usage.rb +9 -0
- data/lib/ruby_llm/active_record/attachment_helpers.rb +7 -1
- data/lib/ruby_llm/active_record/chat_methods.rb +5 -0
- data/lib/ruby_llm/agent.rb +10 -9
- data/lib/ruby_llm/aliases.json +26 -4
- data/lib/ruby_llm/attachment.rb +5 -0
- data/lib/ruby_llm/chat.rb +4 -0
- data/lib/ruby_llm/message.rb +14 -5
- data/lib/ruby_llm/models.json +5358 -1275
- data/lib/ruby_llm/protocols/anthropic/chat.rb +18 -10
- data/lib/ruby_llm/protocols/anthropic/streaming.rb +4 -3
- data/lib/ruby_llm/protocols/anthropic.rb +3 -2
- data/lib/ruby_llm/protocols/bedrock/async_videos.rb +2 -1
- data/lib/ruby_llm/protocols/chat_completions/rerank.rb +8 -1
- data/lib/ruby_llm/protocols/cohere/rerank.rb +8 -1
- data/lib/ruby_llm/protocols/converse/chat.rb +14 -4
- data/lib/ruby_llm/protocols/converse/streaming.rb +8 -0
- data/lib/ruby_llm/protocols/converse/thinking_stream.rb +56 -0
- data/lib/ruby_llm/protocols/gemini/embedding_batches.rb +5 -0
- data/lib/ruby_llm/protocols/interactions/tools.rb +3 -1
- data/lib/ruby_llm/providers/deepseek/responses.rb +0 -1
- data/lib/ruby_llm/providers/mistral/ocr.rb +5 -1
- data/lib/ruby_llm/providers/openrouter/chat.rb +1 -1
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/tasks/ruby_llm.rake +1 -1
- metadata +8 -2
|
@@ -18,6 +18,7 @@ module RubyLLM
|
|
|
18
18
|
COMPACTION_BETA = 'compact-2026-01-12'
|
|
19
19
|
COMPACTION_EDIT_TYPE = 'compact_20260112'
|
|
20
20
|
COUNT_TOKENS_KEYS = %i[model messages system tools tool_choice thinking].freeze
|
|
21
|
+
THINKING_BLOCK_TYPES = %w[thinking redacted_thinking].freeze
|
|
21
22
|
|
|
22
23
|
module_function
|
|
23
24
|
|
|
@@ -303,6 +304,11 @@ module RubyLLM
|
|
|
303
304
|
thinking_block&.dig('signature') || thinking_block&.dig('data')
|
|
304
305
|
end
|
|
305
306
|
|
|
307
|
+
def parse_thinking_blocks(blocks)
|
|
308
|
+
thinking = blocks.select { |block| THINKING_BLOCK_TYPES.include?(block['type']) }
|
|
309
|
+
{ 'anthropic' => thinking } unless thinking.empty?
|
|
310
|
+
end
|
|
311
|
+
|
|
306
312
|
def build_message(data, content:, citations:, thinking:, thinking_signature:, tool_use_blocks:, raw:,
|
|
307
313
|
server_tool_calls: [], raw_content: nil)
|
|
308
314
|
usage = aggregate_usage(data['usage'])
|
|
@@ -316,6 +322,7 @@ module RubyLLM
|
|
|
316
322
|
content: content,
|
|
317
323
|
citations: citations,
|
|
318
324
|
thinking: Thinking.build(text: thinking, signature: thinking_signature),
|
|
325
|
+
raw_reasoning: parse_thinking_blocks(data['content'] || []),
|
|
319
326
|
tool_calls: Tools.parse_tool_calls(tool_use_blocks),
|
|
320
327
|
server_tool_calls: server_tool_calls,
|
|
321
328
|
raw_content: raw_content,
|
|
@@ -357,12 +364,7 @@ module RubyLLM
|
|
|
357
364
|
end
|
|
358
365
|
|
|
359
366
|
def format_basic_message_with_thinking(msg, citations: false, caching: nil)
|
|
360
|
-
content_blocks = []
|
|
361
|
-
|
|
362
|
-
if msg.role == :assistant
|
|
363
|
-
thinking_block = build_thinking_block(msg.thinking)
|
|
364
|
-
content_blocks << thinking_block if thinking_block
|
|
365
|
-
end
|
|
367
|
+
content_blocks = msg.role == :assistant ? format_thinking_blocks(msg) : []
|
|
366
368
|
|
|
367
369
|
append_formatted_content(content_blocks, msg, citations: citations)
|
|
368
370
|
inject_cache_control(content_blocks, caching:) if cache_boundary?(msg, caching:)
|
|
@@ -374,7 +376,7 @@ module RubyLLM
|
|
|
374
376
|
end
|
|
375
377
|
|
|
376
378
|
def format_tool_call_with_thinking(msg, caching: nil)
|
|
377
|
-
content_blocks =
|
|
379
|
+
content_blocks = prepend_thinking_blocks([], msg)
|
|
378
380
|
append_formatted_content(content_blocks, msg) unless msg.content.nil? || msg.content.empty?
|
|
379
381
|
|
|
380
382
|
msg.tool_calls.each_value do |tool_call|
|
|
@@ -393,13 +395,19 @@ module RubyLLM
|
|
|
393
395
|
}
|
|
394
396
|
end
|
|
395
397
|
|
|
396
|
-
def
|
|
397
|
-
|
|
398
|
-
content_blocks.unshift(thinking_block) if thinking_block
|
|
398
|
+
def prepend_thinking_blocks(content_blocks, msg)
|
|
399
|
+
content_blocks.unshift(*format_thinking_blocks(msg))
|
|
399
400
|
|
|
400
401
|
content_blocks
|
|
401
402
|
end
|
|
402
403
|
|
|
404
|
+
def format_thinking_blocks(msg)
|
|
405
|
+
blocks = msg.raw_reasoning['anthropic'] if msg.raw_reasoning.is_a?(Hash)
|
|
406
|
+
return Support::Utils.deep_dup(blocks) if blocks
|
|
407
|
+
|
|
408
|
+
[build_thinking_block(msg.thinking)].compact
|
|
409
|
+
end
|
|
410
|
+
|
|
403
411
|
def build_thinking_block(thinking)
|
|
404
412
|
return nil unless thinking
|
|
405
413
|
|
|
@@ -108,12 +108,13 @@ module RubyLLM
|
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
def stream_end_fields(data)
|
|
111
|
-
return {} unless data['type'] == 'message_stop'
|
|
111
|
+
return {} unless data['type'] == 'message_stop'
|
|
112
112
|
|
|
113
|
-
blocks = @stream_blocks.sort.map { |_index, block| block }
|
|
113
|
+
blocks = (@stream_blocks || {}).sort.map { |_index, block| block }
|
|
114
114
|
{
|
|
115
115
|
server_tool_calls: extract_server_tool_calls(blocks),
|
|
116
|
-
raw_content: blocks
|
|
116
|
+
raw_content: @saw_server_block ? blocks : nil,
|
|
117
|
+
raw_reasoning: parse_thinking_blocks(blocks)
|
|
117
118
|
}
|
|
118
119
|
end
|
|
119
120
|
|
|
@@ -87,8 +87,9 @@ module RubyLLM
|
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
def merge_raw_content(segments)
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
return unless segments.any?(&:raw_content)
|
|
91
|
+
|
|
92
|
+
segments.flat_map { |segment| segment.raw_content || format_message(segment)[:content] }
|
|
92
93
|
end
|
|
93
94
|
|
|
94
95
|
def merge_tool_calls(segments)
|
|
@@ -64,7 +64,8 @@ module RubyLLM
|
|
|
64
64
|
prefix = job.raw.dig('outputDataConfig', 's3OutputDataConfig', 's3Uri')
|
|
65
65
|
raise Error, 'Bedrock video job has no output S3 URI' unless prefix
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
prefix_length = (prefix.rindex(%r{[^/]}) || -1) + 1
|
|
68
|
+
uris = @provider.list_file_uris("#{prefix[0, prefix_length]}/")
|
|
68
69
|
videos = uris.select { |uri| uri.downcase.end_with?('.mp4') }
|
|
69
70
|
raise Error, 'Expected exactly one MP4 in the Bedrock video output' unless videos.one?
|
|
70
71
|
|
|
@@ -38,10 +38,13 @@ module RubyLLM
|
|
|
38
38
|
def parse_rerank_results(data, documents = [])
|
|
39
39
|
Array(data['results']).map do |result|
|
|
40
40
|
index = result['index']
|
|
41
|
+
unless valid_rerank_index?(index, documents)
|
|
42
|
+
raise Error, 'Rerank endpoint returned an invalid document index'
|
|
43
|
+
end
|
|
41
44
|
|
|
42
45
|
RubyLLM::Rerank::Result.new(
|
|
43
46
|
index: index,
|
|
44
|
-
document: rerank_document(result['document']) ||
|
|
47
|
+
document: rerank_document(result['document']) || documents[index],
|
|
45
48
|
score: result['relevance_score']
|
|
46
49
|
)
|
|
47
50
|
end
|
|
@@ -50,6 +53,10 @@ module RubyLLM
|
|
|
50
53
|
def rerank_document(document)
|
|
51
54
|
document.is_a?(Hash) ? document['text'] : document
|
|
52
55
|
end
|
|
56
|
+
|
|
57
|
+
def valid_rerank_index?(index, documents)
|
|
58
|
+
index.is_a?(Integer) && index.between?(0, documents.length - 1)
|
|
59
|
+
end
|
|
53
60
|
end
|
|
54
61
|
end
|
|
55
62
|
end
|
|
@@ -38,14 +38,21 @@ module RubyLLM
|
|
|
38
38
|
def parse_rerank_results(data, documents)
|
|
39
39
|
Array(data['results']).map do |result|
|
|
40
40
|
index = result['index']
|
|
41
|
+
unless valid_rerank_index?(index, documents)
|
|
42
|
+
raise Error, 'Cohere reranking returned an invalid document index'
|
|
43
|
+
end
|
|
41
44
|
|
|
42
45
|
RubyLLM::Rerank::Result.new(
|
|
43
46
|
index: index,
|
|
44
|
-
document: result.dig('document', 'text') ||
|
|
47
|
+
document: result.dig('document', 'text') || documents[index],
|
|
45
48
|
score: result['relevance_score']
|
|
46
49
|
)
|
|
47
50
|
end
|
|
48
51
|
end
|
|
52
|
+
|
|
53
|
+
def valid_rerank_index?(index, documents)
|
|
54
|
+
index.is_a?(Integer) && index.between?(0, documents.length - 1)
|
|
55
|
+
end
|
|
49
56
|
end
|
|
50
57
|
end
|
|
51
58
|
end
|
|
@@ -117,6 +117,7 @@ module RubyLLM
|
|
|
117
117
|
content: text_content,
|
|
118
118
|
citations: citations,
|
|
119
119
|
thinking: Thinking.build(text: thinking_text, signature: thinking_signature),
|
|
120
|
+
raw_reasoning: parse_thinking_blocks(content_blocks),
|
|
120
121
|
tool_calls: parse_tool_calls(content_blocks),
|
|
121
122
|
server_tool_calls: extract_server_tool_calls(content_blocks),
|
|
122
123
|
input_tokens: input_tokens(usage),
|
|
@@ -195,10 +196,7 @@ module RubyLLM
|
|
|
195
196
|
end
|
|
196
197
|
|
|
197
198
|
def format_structured_message_content(msg, citations: false)
|
|
198
|
-
blocks = []
|
|
199
|
-
|
|
200
|
-
thinking_block = format_thinking_block(msg.thinking)
|
|
201
|
-
blocks << thinking_block if msg.role == :assistant && thinking_block
|
|
199
|
+
blocks = msg.role == :assistant ? format_thinking_blocks(msg) : []
|
|
202
200
|
|
|
203
201
|
blocks.concat(
|
|
204
202
|
Media.format_content(msg.content, msg.attachments, used_document_names: @used_document_names, citations:)
|
|
@@ -207,6 +205,13 @@ module RubyLLM
|
|
|
207
205
|
blocks
|
|
208
206
|
end
|
|
209
207
|
|
|
208
|
+
def format_thinking_blocks(msg)
|
|
209
|
+
blocks = msg.raw_reasoning['converse'] if msg.raw_reasoning.is_a?(Hash)
|
|
210
|
+
return Support::Utils.deep_dup(blocks) if blocks
|
|
211
|
+
|
|
212
|
+
[format_thinking_block(msg.thinking)].compact
|
|
213
|
+
end
|
|
214
|
+
|
|
210
215
|
def format_tool_result_block(msg)
|
|
211
216
|
{
|
|
212
217
|
toolResult: {
|
|
@@ -614,6 +619,11 @@ module RubyLLM
|
|
|
614
619
|
[text, signature]
|
|
615
620
|
end
|
|
616
621
|
|
|
622
|
+
def parse_thinking_blocks(content_blocks)
|
|
623
|
+
blocks = content_blocks.select { |block| block['reasoningContent'].is_a?(Hash) }
|
|
624
|
+
{ 'converse' => blocks } unless blocks.empty?
|
|
625
|
+
end
|
|
626
|
+
|
|
617
627
|
def parse_reasoning_content_block(block)
|
|
618
628
|
reasoning_content = block['reasoningContent']
|
|
619
629
|
return [nil, nil] unless reasoning_content.is_a?(Hash)
|
|
@@ -18,6 +18,7 @@ module RubyLLM
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def stream_response(payload, additional_headers = {}, &block)
|
|
21
|
+
@thinking_stream = ThinkingStream.new
|
|
21
22
|
accumulator = RubyLLM::Protocol::StreamAccumulator.new
|
|
22
23
|
decoder = event_stream_decoder
|
|
23
24
|
body = JSON.generate(payload)
|
|
@@ -195,6 +196,7 @@ module RubyLLM
|
|
|
195
196
|
text: extract_thinking_delta(event),
|
|
196
197
|
signature: extract_thinking_signature(event)
|
|
197
198
|
),
|
|
199
|
+
raw_reasoning: streamed_thinking_blocks(event),
|
|
198
200
|
tool_calls: extract_tool_calls(event),
|
|
199
201
|
server_tool_calls: extract_server_tool_call_events(event),
|
|
200
202
|
input_tokens: extract_input_tokens(metadata_usage, usage),
|
|
@@ -206,6 +208,12 @@ module RubyLLM
|
|
|
206
208
|
)
|
|
207
209
|
end
|
|
208
210
|
|
|
211
|
+
def streamed_thinking_blocks(event)
|
|
212
|
+
@thinking_stream ||= ThinkingStream.new
|
|
213
|
+
@thinking_stream.add(event)
|
|
214
|
+
@thinking_stream.raw_reasoning if event.key?('messageStop') || event.key?('stopReason')
|
|
215
|
+
end
|
|
216
|
+
|
|
209
217
|
def extract_finish_reason(event)
|
|
210
218
|
normalize_finish_reason(event.dig('messageStop', 'stopReason') || event['stopReason'])
|
|
211
219
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'base64'
|
|
4
|
+
|
|
5
|
+
module RubyLLM
|
|
6
|
+
module Protocols
|
|
7
|
+
class Converse
|
|
8
|
+
class ThinkingStream # :nodoc: all
|
|
9
|
+
def initialize
|
|
10
|
+
@blocks = {}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def add(event)
|
|
14
|
+
@blocks.clear if event.key?('messageStart')
|
|
15
|
+
part = event['contentBlockStart'] || event['contentBlockDelta'] || event
|
|
16
|
+
index = part['contentBlockIndex']
|
|
17
|
+
return if index.nil?
|
|
18
|
+
|
|
19
|
+
start = part.dig('start', 'reasoningContent')
|
|
20
|
+
@blocks[index] = Support::Utils.deep_dup(start) if start
|
|
21
|
+
delta = part.dig('delta', 'reasoningContent')
|
|
22
|
+
append_delta(index, delta) if delta
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def raw_reasoning
|
|
26
|
+
return if @blocks.empty?
|
|
27
|
+
|
|
28
|
+
{ 'converse' => @blocks.sort.map { |_index, content| { 'reasoningContent' => content } } }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def append_delta(index, delta)
|
|
34
|
+
block = (@blocks[index] ||= {})
|
|
35
|
+
if delta.key?('redactedContent')
|
|
36
|
+
append_redacted(block, delta['redactedContent'])
|
|
37
|
+
else
|
|
38
|
+
text = (block['reasoningText'] ||= { 'text' => '' })
|
|
39
|
+
(delta['reasoningText'] || delta).slice('text', 'signature').each do |key, value|
|
|
40
|
+
text[key] = text[key].to_s + value.to_s
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def append_redacted(block, data)
|
|
46
|
+
block['redactedContent'] = if block['redactedContent']
|
|
47
|
+
Base64.strict_encode64(Base64.decode64(block['redactedContent']) +
|
|
48
|
+
Base64.decode64(data))
|
|
49
|
+
else
|
|
50
|
+
data
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -60,6 +60,11 @@ module RubyLLM
|
|
|
60
60
|
metadata = responses.first.fetch('metadata')
|
|
61
61
|
return if responses.size < metadata.fetch('embedding_count')
|
|
62
62
|
|
|
63
|
+
positions = responses.map { |inline| inline.dig('metadata', 'embedding_index') }
|
|
64
|
+
unless positions.sort == (0...responses.size).to_a
|
|
65
|
+
return [index, nil, batch_failure(key, 'Invalid or duplicate embedding record positions')]
|
|
66
|
+
end
|
|
67
|
+
|
|
63
68
|
vectors = embedding_batch_vectors(responses)
|
|
64
69
|
return [index, nil, batch_failure(key, 'Gemini returned no embedding')] unless vectors
|
|
65
70
|
|
|
@@ -31,7 +31,9 @@ module RubyLLM
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def parse_interaction_arguments(arguments)
|
|
34
|
-
arguments.is_a?(String)
|
|
34
|
+
return {} if arguments.nil? || (arguments.is_a?(String) && arguments.empty?)
|
|
35
|
+
|
|
36
|
+
arguments.is_a?(String) ? JSON.parse(arguments) : arguments
|
|
35
37
|
rescue JSON::ParserError => e
|
|
36
38
|
raise ToolCallParseError.new(finish_reason: :tool_calls), cause: e
|
|
37
39
|
end
|
|
@@ -8,7 +8,6 @@ module RubyLLM
|
|
|
8
8
|
# instead of summaries, both in responses and in the stream.
|
|
9
9
|
class Responses < Protocols::Responses
|
|
10
10
|
SERVER_TOOL_ALIASES = {
|
|
11
|
-
web_search: { tool: { type: 'web_search' } },
|
|
12
11
|
apply_patch: { tool: { type: 'custom', name: 'apply_patch' } }
|
|
13
12
|
}.freeze
|
|
14
13
|
|
|
@@ -22,7 +22,7 @@ module RubyLLM
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def ocr_document_part(attachment)
|
|
25
|
-
reference = attachment.url? ? attachment.source.to_s : attachment
|
|
25
|
+
reference = attachment.url? ? attachment.source.to_s : ocr_data_uri(attachment)
|
|
26
26
|
|
|
27
27
|
if attachment.image?
|
|
28
28
|
{ type: 'image_url', image_url: reference }
|
|
@@ -31,6 +31,10 @@ module RubyLLM
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
def ocr_data_uri(attachment)
|
|
35
|
+
"data:#{attachment.mime_type};base64,#{attachment.encoded}"
|
|
36
|
+
end
|
|
37
|
+
|
|
34
38
|
def parse_ocr_response(response, model:)
|
|
35
39
|
data = response.body
|
|
36
40
|
|
|
@@ -80,7 +80,7 @@ module RubyLLM
|
|
|
80
80
|
|
|
81
81
|
def format_thinking(msg)
|
|
82
82
|
return {} unless msg.role == :assistant
|
|
83
|
-
return { reasoning_details: msg.raw_reasoning } if msg.raw_reasoning
|
|
83
|
+
return { reasoning_details: msg.raw_reasoning } if msg.raw_reasoning.is_a?(Array)
|
|
84
84
|
|
|
85
85
|
thinking = msg.thinking
|
|
86
86
|
return {} unless thinking
|
data/lib/ruby_llm/version.rb
CHANGED
data/lib/tasks/ruby_llm.rake
CHANGED
|
@@ -7,7 +7,7 @@ namespace :ruby_llm do
|
|
|
7
7
|
task action => :environment do
|
|
8
8
|
require 'generators/ruby_llm/upgrade/upgrade_migration'
|
|
9
9
|
|
|
10
|
-
RubyLLM::Generators::UpgradeMigration.
|
|
10
|
+
RubyLLM::Generators::UpgradeMigration.for.public_send(action)
|
|
11
11
|
puts "RubyLLM copy upgrade: #{action} completed"
|
|
12
12
|
end
|
|
13
13
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_llm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.0.
|
|
4
|
+
version: 2.0.0.rc3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Carmine Paolino
|
|
@@ -275,6 +275,11 @@ files:
|
|
|
275
275
|
- lib/generators/ruby_llm/tool/templates/tool_call.html.erb.tt
|
|
276
276
|
- lib/generators/ruby_llm/tool/templates/tool_result.html.erb.tt
|
|
277
277
|
- lib/generators/ruby_llm/tool/tool_generator.rb
|
|
278
|
+
- lib/generators/ruby_llm/upgrade/legacy_content_sql.rb
|
|
279
|
+
- lib/generators/ruby_llm/upgrade/online_copy_migration.rb
|
|
280
|
+
- lib/generators/ruby_llm/upgrade/online_copy_migration/data.rb
|
|
281
|
+
- lib/generators/ruby_llm/upgrade/online_copy_migration/journal.rb
|
|
282
|
+
- lib/generators/ruby_llm/upgrade/online_copy_migration/verification.rb
|
|
278
283
|
- lib/generators/ruby_llm/upgrade/templates/backfill_v2_data.rb.tt
|
|
279
284
|
- lib/generators/ruby_llm/upgrade/templates/cleanup_v2_upgrade.rb.tt
|
|
280
285
|
- lib/generators/ruby_llm/upgrade/templates/finish_v2_upgrade.rb.tt
|
|
@@ -379,6 +384,7 @@ files:
|
|
|
379
384
|
- lib/ruby_llm/protocols/converse/chat.rb
|
|
380
385
|
- lib/ruby_llm/protocols/converse/media.rb
|
|
381
386
|
- lib/ruby_llm/protocols/converse/streaming.rb
|
|
387
|
+
- lib/ruby_llm/protocols/converse/thinking_stream.rb
|
|
382
388
|
- lib/ruby_llm/protocols/deepgram.rb
|
|
383
389
|
- lib/ruby_llm/protocols/deepgram/models.rb
|
|
384
390
|
- lib/ruby_llm/protocols/deepgram/speech.rb
|
|
@@ -611,7 +617,7 @@ metadata:
|
|
|
611
617
|
funding_uri: https://github.com/sponsors/crmne
|
|
612
618
|
rubygems_mfa_required: 'true'
|
|
613
619
|
post_install_message: |
|
|
614
|
-
RubyLLM 2.0
|
|
620
|
+
RubyLLM 2.0.0.rc3
|
|
615
621
|
|
|
616
622
|
2.0 renames several APIs and changes what message content returns. Coming
|
|
617
623
|
from 1.x? Read the upgrade guide before you boot:
|