lex-bedrock 0.2.1 → 0.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee5a83a0ee7afd53d1d8f496bd8382332b1312939b3a49cbdf8c86b2269ff6ab
4
- data.tar.gz: 467176f83f6f58de4a7640bea5f2fcd6b75be4e2a8d5a77d4fa8f3fe82854c2b
3
+ metadata.gz: 9c54111009d79155a7a9b85e0ec03a17b6b48800ce5dd641df7286637471114d
4
+ data.tar.gz: cb5f69ffe79c02ba38ba60c205b5215d7d8500851616ff5933c0e61ecf2f5b43
5
5
  SHA512:
6
- metadata.gz: 106a987eb8c0d61d3c8fc1e409b0168d95277db70f98fba5ee8ebd0dbe9b74c3770837b052b6cb04b32aae8bfd639511de8b907dfaccee09ee72c563792ae051
7
- data.tar.gz: d8c81a605d36fd3e6b572580ad4a092a1a7bf913e5edf51e5e26302facf20cd2248da4311fcbf1867fe6cfc35eea78bea61c71c4c7ca0ff43c91d99b920482f6
6
+ metadata.gz: 6cf4b797406f46d5b8b0f506913e429b90dc7aca0f17ead791476a1ab629f962c3c6495cc04f0cc16b9dc0be0b10704ac8546dbd164249aea378b30e9c1c290c
7
+ data.tar.gz: 1e886593369d42af3426a4bf30cda859642157d0f9199416b0ddb52c0ee5caf5621b6cbb0ad1cf2da324e112ade51c3cd2344a5ad3cecc5541dbb64a07166a4b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.2] - 2026-04-06
4
+
5
+ ### Added
6
+ - Broker soft consumer in Helpers::Client for AWS credential resolution via Identity::Broker (Phase 8 Wave 2)
7
+
3
8
  ## [0.2.1] - 2026-03-31
4
9
 
5
10
  ### Added
data/CLAUDE.md CHANGED
@@ -6,29 +6,36 @@
6
6
 
7
7
  ## Purpose
8
8
 
9
- Legion Extension that connects LegionIO to AWS Bedrock for foundation model inference. Provides runners for the Converse API, raw InvokeModel, and model listing using the AWS SDK (not Faraday).
9
+ Legion Extension that connects LegionIO to AWS Bedrock for foundation model inference. Provides runners for the Converse API, raw InvokeModel, model listing, token counting, and inference profile management using the AWS SDK (not Faraday).
10
10
 
11
11
  **GitHub**: https://github.com/LegionIO/lex-bedrock
12
12
  **License**: MIT
13
- **Version**: 0.1.2
14
- **Specs**: 38 examples
13
+ **Version**: 0.2.2
14
+ **Specs**: 120 examples (13 spec files)
15
15
 
16
16
  ## Architecture
17
17
 
18
18
  ```
19
19
  Legion::Extensions::Bedrock
20
20
  ├── Runners/
21
- │ ├── Converse # create(model_id:, messages:, access_key_id:, secret_access_key:, ...)
22
- │ ├── Invoke # invoke_model(model_id:, body:, access_key_id:, secret_access_key:, ...)
23
- └── Models # list(access_key_id:, secret_access_key:, ...), get(model_id:, ...)
21
+ │ ├── Converse # create, create_stream, create_with_thinking
22
+ │ ├── Invoke # invoke_model
23
+ ├── Models # list, get
24
+ │ ├── Tokens # count_tokens
25
+ │ └── Profiles # list_inference_profiles, get_inference_profile, resolve_profile_id
24
26
  ├── Helpers/
25
- └── Client # AWS SDK client factories (module, not Faraday)
27
+ ├── Client # AWS SDK client factories (module, not Faraday)
28
+ │ ├── Credentials # credential resolution helpers
29
+ │ ├── Errors # error handling + with_retry
30
+ │ ├── ModelRegistry # canonical model name -> Bedrock cross-region profile ID mapping
31
+ │ ├── Thinking # extended thinking field builders
32
+ │ └── Usage # usage normalization
26
33
  └── Client # Standalone client class (includes all runners, holds @config)
27
34
  ```
28
35
 
29
36
  `Helpers::Client` is a **module** with two factory methods:
30
- - `bedrock_runtime_client(...)` — builds `Aws::BedrockRuntime::Client` (used by Converse and Invoke runners)
31
- - `bedrock_client(...)` — builds `Aws::Bedrock::Client` (used by Models runner)
37
+ - `bedrock_runtime_client(...)` — builds `Aws::BedrockRuntime::Client` (used by Converse, Invoke, Tokens runners)
38
+ - `bedrock_client(...)` — builds `Aws::Bedrock::Client` (used by Models, Profiles runners)
32
39
 
33
40
  `DEFAULT_REGION` is `'us-east-2'`. All credential kwargs (`access_key_id:`, `secret_access_key:`, `region:`, `session_token:`) are passed through to the AWS SDK constructors. `session_token:` is optional and omitted if nil.
34
41
 
@@ -36,25 +43,32 @@ Legion::Extensions::Bedrock
36
43
 
37
44
  - This is the only extension in extensions-ai that uses the AWS SDK instead of Faraday. There is no HTTP connection object — SDK clients handle transport.
38
45
  - `Invoke#invoke_model` uses `::JSON.dump` and `::JSON.parse` (stdlib, explicit `::` prefix) to avoid namespace collision with `Legion::JSON`.
39
- - `Converse#create` returns `{ result: response.output, usage: response.usage, stop_reason: response.stop_reason }` — three keys, unlike other runners which return only `{ result: ... }`.
40
- - `Models#list` returns `{ models: response.model_summaries }` and `Models#get` returns `{ model: response.model_details }`.
46
+ - `Converse#create` returns `{ result: response.output, usage: response.usage, stop_reason: response.stop_reason }`.
47
+ - `Converse#create_stream` accepts a block and yields `{ type: :delta, text: }`, `{ type: :stop, stop_reason: }`, `{ type: :usage, usage: }` events. Returns `{ result: accumulated_text, usage:, stop_reason: }`.
48
+ - `Converse#create_with_thinking` wraps `create` with `Helpers::Thinking.build_thinking_fields`. Supports `budget_tokens:`, `adaptive:`, `extra_betas:`.
49
+ - `Tokens#count_tokens` uses `client.count_tokens(...)` SDK call; returns `{ input_token_count: response.input_tokens }`.
50
+ - `Profiles` runner lists, gets, and resolves AWS cross-region inference profiles. `resolve_profile_id` finds the profile ARN for a canonical model ID.
51
+ - `Helpers::ModelRegistry` maps canonical model names (e.g. `'claude-sonnet-4-6'`) to Bedrock cross-region profile IDs (e.g. `'us.anthropic.claude-sonnet-4-6'`). Use `ModelRegistry.resolve(model_id)` before passing to SDK calls.
52
+ - `Helpers::Thinking` constants: `THINKING_BETA = 'interleaved-thinking-2025-05-14'`, `CONTEXT_1M_BETA = 'context-1m-2025-08-07'`, `TOOL_SEARCH_BETA = 'tool-search-tool-2025-10-19'`. Supports both `adaptive` and `enabled` thinking modes.
41
53
  - `include Legion::Extensions::Helpers::Lex` is guarded with `const_defined?` pattern.
42
54
 
43
55
  ## Dependencies
44
56
 
45
57
  | Gem | Purpose |
46
58
  |-----|---------|
47
- | `aws-sdk-bedrock` | Bedrock management API (model listing) |
48
- | `aws-sdk-bedrockruntime` | Bedrock runtime API (inference) |
59
+ | `aws-sdk-bedrock` | Bedrock management API (model listing, inference profiles) |
60
+ | `aws-sdk-bedrockruntime` | Bedrock runtime API (inference, streaming, token counting) |
61
+ | `legion-cache`, `legion-crypt`, `legion-data`, `legion-json`, `legion-logging`, `legion-settings`, `legion-transport` | LegionIO core |
49
62
 
50
63
  ## Testing
51
64
 
52
65
  ```bash
53
66
  bundle install
54
- bundle exec rspec # 38 examples
67
+ bundle exec rspec # 120 examples
55
68
  bundle exec rubocop
56
69
  ```
57
70
 
58
71
  ---
59
72
 
60
73
  **Maintained By**: Matthew Iverson (@Esity)
74
+ **Last Updated**: 2026-04-06
data/README.md CHANGED
@@ -4,7 +4,7 @@ Legion Extension that connects LegionIO to AWS Bedrock for foundation model infe
4
4
 
5
5
  ## Purpose
6
6
 
7
- Wraps the AWS Bedrock SDK as named runners consumable by any LegionIO task chain. Provides the Converse API (multi-turn chat), raw InvokeModel (direct model invocation), and foundation model listing. Uses the AWS SDK directly — no Faraday. Use this extension when you need direct access to the Bedrock API surface within the LEX runner/actor lifecycle. For simple chat/embed workflows, consider `legion-llm` instead.
7
+ Wraps the AWS Bedrock SDK as named runners consumable by any LegionIO task chain. Provides the Converse API (multi-turn chat with streaming and extended thinking), raw InvokeModel (direct model invocation), foundation model listing, token counting, and inference profile management. Uses the AWS SDK directly — no Faraday. Use this extension when you need direct access to the Bedrock API surface within the LEX runner/actor lifecycle. For simple chat/embed workflows, consider `legion-llm` instead.
8
8
 
9
9
  ## Installation
10
10
 
@@ -40,17 +40,46 @@ result = client.list
40
40
 
41
41
  # Converse API
42
42
  result = client.create(
43
- model_id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
43
+ model_id: 'us.anthropic.claude-sonnet-4-6',
44
44
  messages: [{ role: 'user', content: [{ text: 'Hello' }] }]
45
45
  )
46
46
  # => { result: ..., usage: ..., stop_reason: 'end_turn' }
47
47
 
48
+ # Streaming Converse
49
+ client.create_stream(
50
+ model_id: 'us.anthropic.claude-sonnet-4-6',
51
+ messages: [{ role: 'user', content: [{ text: 'Tell me a story.' }] }]
52
+ ) do |event|
53
+ case event[:type]
54
+ when :delta then print event[:text]
55
+ when :stop then puts "\nStop: #{event[:stop_reason]}"
56
+ when :usage then puts event[:usage].inspect
57
+ end
58
+ end
59
+
60
+ # Extended thinking
61
+ result = client.create_with_thinking(
62
+ model_id: 'us.anthropic.claude-sonnet-4-6',
63
+ messages: [{ role: 'user', content: [{ text: 'Solve this step by step.' }] }],
64
+ budget_tokens: 8192
65
+ )
66
+
67
+ # Token counting
68
+ result = client.count_tokens(
69
+ model_id: 'us.anthropic.claude-sonnet-4-6',
70
+ messages: [{ role: 'user', content: [{ text: 'Hello' }] }]
71
+ )
72
+ # => { input_token_count: 10 }
73
+
48
74
  # Raw InvokeModel
49
75
  result = client.invoke_model(
50
76
  model_id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
51
77
  body: { prompt: 'Hello', max_tokens: 256 }
52
78
  )
53
- # => { result: { ... }, content_type: 'application/json' }
79
+
80
+ # Resolve model ID via ModelRegistry
81
+ resolved = Legion::Extensions::Bedrock::Helpers::ModelRegistry.resolve('claude-sonnet-4-6')
82
+ # => 'us.anthropic.claude-sonnet-4-6'
54
83
  ```
55
84
 
56
85
  ### Runner Modules
@@ -59,15 +88,45 @@ result = client.invoke_model(
59
88
  include Legion::Extensions::Bedrock::Runners::Models
60
89
  include Legion::Extensions::Bedrock::Runners::Converse
61
90
  include Legion::Extensions::Bedrock::Runners::Invoke
91
+ include Legion::Extensions::Bedrock::Runners::Tokens
92
+ include Legion::Extensions::Bedrock::Runners::Profiles
62
93
  ```
63
94
 
64
95
  ## API Coverage
65
96
 
66
97
  | Runner | Methods |
67
98
  |--------|---------|
68
- | `Converse` | `create` |
99
+ | `Converse` | `create`, `create_stream`, `create_with_thinking` |
69
100
  | `Invoke` | `invoke_model` |
70
101
  | `Models` | `list`, `get` |
102
+ | `Tokens` | `count_tokens` |
103
+ | `Profiles` | `list_inference_profiles`, `get_inference_profile`, `resolve_profile_id` |
104
+
105
+ ## Model Registry
106
+
107
+ `Helpers::ModelRegistry` maps canonical model names to Bedrock cross-region inference profile IDs:
108
+
109
+ ```ruby
110
+ Legion::Extensions::Bedrock::Helpers::ModelRegistry.resolve('claude-sonnet-4-6')
111
+ # => 'us.anthropic.claude-sonnet-4-6'
112
+
113
+ Legion::Extensions::Bedrock::Helpers::ModelRegistry.all
114
+ # => { 'claude-3-5-haiku-20241022' => 'us.anthropic.claude-3-5-haiku-20241022-v1:0', ... }
115
+ ```
116
+
117
+ ## Extended Thinking
118
+
119
+ `Helpers::Thinking` provides field builders for Anthropic extended thinking on Bedrock:
120
+
121
+ ```ruby
122
+ # Fixed budget
123
+ fields = Legion::Extensions::Bedrock::Helpers::Thinking.build_thinking_fields(budget_tokens: 8192)
124
+
125
+ # Adaptive thinking
126
+ fields = Legion::Extensions::Bedrock::Helpers::Thinking.build_thinking_fields(adaptive: true)
127
+ ```
128
+
129
+ Constants: `THINKING_BETA = 'interleaved-thinking-2025-05-14'`, `CONTEXT_1M_BETA = 'context-1m-2025-08-07'`, `TOOL_SEARCH_BETA = 'tool-search-tool-2025-10-19'`.
71
130
 
72
131
  ## Related
73
132
 
@@ -75,6 +134,10 @@ include Legion::Extensions::Bedrock::Runners::Invoke
75
134
  - `legion-llm` — High-level LLM interface including Bedrock via ruby_llm
76
135
  - `extensions-ai/CLAUDE.md` — Architecture patterns shared across all AI extensions
77
136
 
137
+ ## Version
138
+
139
+ 0.2.1
140
+
78
141
  ## License
79
142
 
80
143
  MIT
@@ -15,21 +15,17 @@ module Legion
15
15
  def bedrock_runtime_client(access_key_id: nil, secret_access_key: nil,
16
16
  region: DEFAULT_REGION, session_token: nil,
17
17
  credentials: nil, **)
18
- Aws::BedrockRuntime::Client.new(
19
- region:,
20
- credentials: credentials || build_credentials(access_key_id:, secret_access_key:,
21
- session_token:)
22
- )
18
+ credentials ||= build_credentials(access_key_id:, secret_access_key:, session_token:)
19
+ credentials ||= resolve_broker_credentials
20
+ Aws::BedrockRuntime::Client.new(region:, credentials:)
23
21
  end
24
22
 
25
23
  def bedrock_client(access_key_id: nil, secret_access_key: nil,
26
24
  region: DEFAULT_REGION, session_token: nil,
27
25
  credentials: nil, **)
28
- Aws::Bedrock::Client.new(
29
- region:,
30
- credentials: credentials || build_credentials(access_key_id:, secret_access_key:,
31
- session_token:)
32
- )
26
+ credentials ||= build_credentials(access_key_id:, secret_access_key:, session_token:)
27
+ credentials ||= resolve_broker_credentials
28
+ Aws::Bedrock::Client.new(region:, credentials:)
33
29
  end
34
30
 
35
31
  def region_for_model(model_id:, region: nil)
@@ -48,6 +44,18 @@ module Legion
48
44
  settings_region || DEFAULT_REGION
49
45
  end
50
46
 
47
+ def resolve_broker_credentials
48
+ return nil unless defined?(Legion::Identity::Broker)
49
+
50
+ renewer = Legion::Identity::Broker.renewer_for(:aws)
51
+ return nil unless renewer&.provider.respond_to?(:current_credentials)
52
+
53
+ renewer.provider.current_credentials
54
+ rescue StandardError => e
55
+ log.warn("resolve_broker_credentials failed: #{e.message}")
56
+ nil
57
+ end
58
+
51
59
  def build_credentials(access_key_id:, secret_access_key:, session_token:)
52
60
  return nil if access_key_id.nil?
53
61
 
@@ -58,7 +66,7 @@ module Legion
58
66
  end
59
67
  end
60
68
 
61
- private_class_method :build_credentials
69
+ private_class_method :build_credentials, :resolve_broker_credentials
62
70
  end
63
71
  end
64
72
  end
@@ -3,7 +3,7 @@
3
3
  module Legion
4
4
  module Extensions
5
5
  module Bedrock
6
- VERSION = '0.2.1'
6
+ VERSION = '0.2.2'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-bedrock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity