lex-llm-bedrock 0.3.8 → 0.3.9
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/CHANGELOG.md +5 -0
- data/lib/legion/extensions/llm/bedrock/provider.rb +83 -14
- data/lib/legion/extensions/llm/bedrock/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d0b15f1168f45e6f11211963cc8c0939085562bd92e720bcd74426367824318
|
|
4
|
+
data.tar.gz: e68d8865e321e62f0b7c54cf16a573286174626531229b325e53b0aecbc8c3ea
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ac5ed2ff6e4d586891edc3d05a8935cd32b25b561862a882c04a17d2c42324f8cfde527338c8d464cc8373d06dfa4b758fc3a7ab4c1ac70072d22d9998799207
|
|
7
|
+
data.tar.gz: 1e6f4bd752aa5fe9eeb033426405718826135763e2f6974674a7238ffbf74134024ad8f164962d02dc908aa8276417451087c7092e623beda5e0df58977efbf4
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.9 - 2026-05-18
|
|
4
|
+
|
|
5
|
+
- Fix streaming tool call parsing: `stream_converse` now handles content_block_start/delta/stop events for tool_use blocks, capturing tool ids, names, and accumulated input JSON. Previously only text deltas were captured and tool calls were silently dropped.
|
|
6
|
+
|
|
7
|
+
|
|
3
8
|
## 0.3.8 - 2026-05-13
|
|
4
9
|
|
|
5
10
|
- Auto-prefix `us.` on `inference_profile_id` for Anthropic, Meta, Mistral, Cohere, and AI21 models at API call time.
|
|
@@ -474,30 +474,99 @@ module Legion
|
|
|
474
474
|
end
|
|
475
475
|
|
|
476
476
|
def stream_converse(request, fallback_model)
|
|
477
|
-
|
|
478
|
-
final_usage = nil
|
|
477
|
+
state = { accumulated: +'', final_usage: nil, stop_reason: nil, tool_use_blocks: [], current_tool_use: nil }
|
|
479
478
|
|
|
480
479
|
runtime_client.converse_stream(**request) do |stream|
|
|
481
|
-
stream
|
|
482
|
-
|
|
483
|
-
|
|
480
|
+
wire_stream_handlers(stream, state, fallback_model) { |chunk| yield chunk if block_given? }
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
Legion::Extensions::Llm::Message.new(
|
|
484
|
+
role: :assistant,
|
|
485
|
+
content: state[:accumulated],
|
|
486
|
+
model_id: fallback_model,
|
|
487
|
+
tool_calls: build_stream_tool_calls(state[:tool_use_blocks]),
|
|
488
|
+
input_tokens: value(state[:final_usage], :input_tokens),
|
|
489
|
+
output_tokens: value(state[:final_usage], :output_tokens),
|
|
490
|
+
stop_reason: state[:stop_reason]
|
|
491
|
+
)
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
def wire_stream_handlers(stream, state, fallback_model, &)
|
|
495
|
+
wire_block_start(stream, state)
|
|
496
|
+
wire_block_delta(stream, state, fallback_model, &)
|
|
497
|
+
wire_block_stop(stream, state)
|
|
498
|
+
wire_message_stop(stream, state)
|
|
499
|
+
stream.on_metadata_event { |event| state[:final_usage] = value(event, :usage) }
|
|
500
|
+
end
|
|
484
501
|
|
|
485
|
-
|
|
502
|
+
def wire_block_start(stream, state)
|
|
503
|
+
return unless stream.respond_to?(:on_content_block_start_event)
|
|
504
|
+
|
|
505
|
+
stream.on_content_block_start_event do |event|
|
|
506
|
+
start = value(event, :start)
|
|
507
|
+
tool_start = value(start, :tool_use) if start
|
|
508
|
+
next unless tool_start
|
|
509
|
+
|
|
510
|
+
state[:current_tool_use] = {
|
|
511
|
+
tool_use_id: value(tool_start, :tool_use_id),
|
|
512
|
+
name: value(tool_start, :name),
|
|
513
|
+
input_json: +''
|
|
514
|
+
}
|
|
515
|
+
end
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
def wire_block_delta(stream, state, fallback_model)
|
|
519
|
+
stream.on_content_block_delta_event do |event|
|
|
520
|
+
delta = value(event, :delta)
|
|
521
|
+
text = value(delta, :text)
|
|
522
|
+
if text
|
|
523
|
+
state[:accumulated] << text
|
|
486
524
|
if block_given?
|
|
487
525
|
yield Legion::Extensions::Llm::Chunk.new(role: :assistant, content: text,
|
|
488
526
|
model_id: fallback_model)
|
|
489
527
|
end
|
|
490
528
|
end
|
|
491
|
-
|
|
529
|
+
|
|
530
|
+
tool_input = value(delta, :tool_use)
|
|
531
|
+
next unless tool_input && state[:current_tool_use]
|
|
532
|
+
|
|
533
|
+
input_chunk = value(tool_input, :input)
|
|
534
|
+
state[:current_tool_use][:input_json] << input_chunk.to_s if input_chunk
|
|
492
535
|
end
|
|
536
|
+
end
|
|
493
537
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
538
|
+
def wire_block_stop(stream, state)
|
|
539
|
+
return unless stream.respond_to?(:on_content_block_stop_event)
|
|
540
|
+
|
|
541
|
+
stream.on_content_block_stop_event do |_event|
|
|
542
|
+
next unless state[:current_tool_use]
|
|
543
|
+
|
|
544
|
+
state[:tool_use_blocks] << state[:current_tool_use]
|
|
545
|
+
state[:current_tool_use] = nil
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
def wire_message_stop(stream, state)
|
|
550
|
+
return unless stream.respond_to?(:on_message_stop_event)
|
|
551
|
+
|
|
552
|
+
stream.on_message_stop_event do |event|
|
|
553
|
+
state[:stop_reason] = value(event, :stop_reason)
|
|
554
|
+
end
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
def build_stream_tool_calls(tool_use_blocks)
|
|
558
|
+
return nil if tool_use_blocks.empty?
|
|
559
|
+
|
|
560
|
+
tool_use_blocks.to_h do |block|
|
|
561
|
+
input = begin
|
|
562
|
+
Legion::JSON.load(block[:input_json])
|
|
563
|
+
rescue StandardError
|
|
564
|
+
{}
|
|
565
|
+
end
|
|
566
|
+
name = block[:name]
|
|
567
|
+
id = block[:tool_use_id] || name
|
|
568
|
+
[id, Legion::Extensions::Llm::ToolCall.new(id: id, name: name, arguments: input)]
|
|
569
|
+
end
|
|
501
570
|
end
|
|
502
571
|
|
|
503
572
|
def parse_embedding_response(response, model:)
|