omniai-anthropic 3.1.1 → 3.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5077178a43cec44b1c90e0fc272ee5b1e6e8b025387ed6bb71c2238514187631
4
- data.tar.gz: 416834202514d4acfa5e742a8dba508f8aecd9042a5cc5ecff16d22366406cd7
3
+ metadata.gz: 1470defc13c0a21221912b1790674f09b45ccbda95b89bfeafb4d6c922af317e
4
+ data.tar.gz: 4ce00f8604c741bfda656a7557e5f97811712320b8486c602c90edba0c0e81e7
5
5
  SHA512:
6
- metadata.gz: bab092c2f66f0ac792f09574974afdaa0f8e6a575482661c168374089aa5380202feeaaa617a2259fd81718f738b6c68c0280bba438ba35de7ae66d154f0a555
7
- data.tar.gz: 5e4b8e0d4db1e9769031d8c11e11eedd4d6ad4ff14c6f06d48ae9271138cbcd187ebf379ad9059907fdf5f92c79004f6973522bc58561ac0b1fc1c456d70e3c2
6
+ metadata.gz: 284bf4047b7bfeb785857a4b704f0f990d2203f7ad41a0dff2108453d2ff666377682fb89e2ef65c39ab92ff4f0263285a57a7b9c14b962a9903ee11624f1bf7
7
+ data.tar.gz: 27577003e3d1c640c7052e2023a93b87cb4179be49bf019eb1c3107e2b843d319905e9abdb079838a6f757caffa36a7dede04f114452e26e86dcc0a6c65a2394
data/README.md CHANGED
@@ -61,7 +61,7 @@ completion.text # 'The capital of Canada is Ottawa.'
61
61
 
62
62
  #### Model
63
63
 
64
- `model` takes an optional string (default is `claude-3-haiku-20240307`):
64
+ `model` takes an optional string (default is `claude-sonnet-4-6`):
65
65
 
66
66
  ```ruby
67
67
  completion = client.chat('Provide code for fibonacci', model: OmniAI::Anthropic::Chat::Model::CLAUDE_SONNET)
@@ -21,7 +21,7 @@ module OmniAI
21
21
  CLAUDE_3_5_HAIKU_20241022 = "claude-3-5-haiku-20241022"
22
22
  CLAUDE_HAIKU_4_5_20251001 = "claude-haiku-4-5-20251001"
23
23
  CLAUDE_3_OPUS_20240229 = "claude-3-opus-20240229"
24
- CLAUDE_3_SONNET_20240209 = "claude-3-sonnet-20240229"
24
+ CLAUDE_3_SONNET_20240229 = "claude-3-sonnet-20240229"
25
25
  CLAUDE_3_SONNET_20240307 = "claude-3-sonnet-20240307"
26
26
  CLAUDE_3_5_SONNET_20240620 = "claude-3-5-sonnet-20240620"
27
27
  CLAUDE_3_5_SONNET_20241022 = "claude-3-5-sonnet-20241022"
@@ -35,19 +35,23 @@ module OmniAI
35
35
  CLAUDE_OPUS_4_20250514 = "claude-opus-4-20250514"
36
36
  CLAUDE_OPUS_4_1_20250805 = "claude-opus-4-1-20250805"
37
37
  CLAUDE_OPUS_4_5_20251101 = "claude-opus-4-5-20251101"
38
+ CLAUDE_OPUS_4_6_20260217 = "claude-opus-4-6-20260217"
38
39
  CLAUDE_SONNET_4_20250514 = "claude-sonnet-4-20250514"
39
- CLAUDE_SONNET_4_5_20240620 = "claude-sonnet-4-5-20250929"
40
+ CLAUDE_SONNET_4_5_20250929 = "claude-sonnet-4-5-20250929"
41
+ CLAUDE_SONNET_4_6_20260217 = "claude-sonnet-4-6-20260217"
40
42
 
41
43
  CLAUDE_HAIKU_4_5 = "claude-haiku-4-5"
42
44
  CLAUDE_OPUS_4_0 = "claude-opus-4-0"
43
45
  CLAUDE_OPUS_4_1 = "claude-opus-4-1"
44
46
  CLAUDE_OPUS_4_5 = "claude-opus-4-5"
47
+ CLAUDE_OPUS_4_6 = "claude-opus-4-6"
45
48
  CLAUDE_SONNET_4_0 = "claude-sonnet-4-0"
46
49
  CLAUDE_SONNET_4_5 = "claude-sonnet-4-5"
50
+ CLAUDE_SONNET_4_6 = "claude-sonnet-4-6"
47
51
 
48
52
  CLAUDE_HAIKU = CLAUDE_HAIKU_4_5
49
- CLAUDE_OPUS = CLAUDE_OPUS_4_5
50
- CLAUDE_SONNET = CLAUDE_SONNET_4_5
53
+ CLAUDE_OPUS = CLAUDE_OPUS_4_6
54
+ CLAUDE_SONNET = CLAUDE_SONNET_4_6
51
55
  end
52
56
 
53
57
  DEFAULT_MODEL = Model::CLAUDE_SONNET
@@ -82,40 +86,51 @@ module OmniAI
82
86
  end
83
87
 
84
88
  # @return [Hash]
89
+ #
90
+ # NOTE: Anthropic requires temperature=1 (default) when thinking is enabled,
91
+ # so temperature is omitted from the payload when thinking_config is present.
85
92
  def payload
86
- data = OmniAI::Anthropic.config.chat_options.merge({
87
- model: @model,
88
- messages:,
89
- system:,
90
- stream: stream? || nil,
91
- temperature: thinking_config ? nil : @temperature, # Anthropic requires temperature=1 (default) when thinking
92
- tools: tools_payload,
93
- thinking: thinking_config,
94
- }).compact
95
-
96
- # When thinking is enabled, ensure max_tokens > budget_tokens
97
- data[:max_tokens] = thinking_max_tokens if thinking_config
98
-
99
- data
93
+ OmniAI::Anthropic.config.chat_options
94
+ .merge({
95
+ model: @model,
96
+ messages:,
97
+ system:,
98
+ stream: stream? || nil,
99
+ temperature: thinking_config ? nil : @temperature,
100
+ tools: tools_payload,
101
+ thinking: thinking_config,
102
+ })
103
+ .merge({ max_tokens: thinking_max_tokens, output_config: }.compact)
104
+ .compact
100
105
  end
101
106
 
102
107
  # Translates unified thinking option to Anthropic's native format.
103
108
  # Example: `thinking: { budget_tokens: 10000 }` becomes `{ type: "enabled", budget_tokens: 10000 }`
109
+ # Example: `thinking: { effort: nil }` becomes `{ type: "adaptive" }` (Claude decides)
110
+ # Example: `thinking: { effort: "medium" }` becomes `{ type: "adaptive" }` + output_config
104
111
  # @return [Hash, nil]
105
112
  def thinking_config
113
+ return @thinking_config if defined?(@thinking_config)
114
+
106
115
  thinking = @options[:thinking]
107
- return unless thinking
108
116
 
109
- case thinking
110
- when true then { type: "enabled", budget_tokens: 10_000 }
111
- when Hash then { type: "enabled" }.merge(thinking)
112
- end
117
+ @thinking_config = case thinking
118
+ when true then { type: "enabled", budget_tokens: 10_000 }
119
+ when Hash
120
+ if thinking.key?(:effort)
121
+ { type: "adaptive" }
122
+ else
123
+ { type: "enabled" }.merge(thinking)
124
+ end
125
+ end
113
126
  end
114
127
 
115
128
  # Returns max_tokens ensuring it's greater than budget_tokens when thinking is enabled.
116
- # @return [Integer]
129
+ # @return [Integer, nil]
117
130
  def thinking_max_tokens
118
- budget = thinking_config[:budget_tokens]
131
+ budget = thinking_config&.dig(:budget_tokens)
132
+ return unless budget
133
+
119
134
  base = @options[:max_tokens] || OmniAI::Anthropic.config.chat_options[:max_tokens] || 0
120
135
  # Ensure max_tokens > budget_tokens (default to budget + 8000 for response)
121
136
  [base, budget + 8_000].max
@@ -177,6 +192,19 @@ module OmniAI
177
192
  def tools_payload
178
193
  @tools.map { |tool| tool.serialize(context:) } if @tools&.any?
179
194
  end
195
+
196
+ # @return [Boolean]
197
+ def adaptive_thinking?
198
+ thinking_config&.dig(:type) == "adaptive"
199
+ end
200
+
201
+ # @return [Hash, nil]
202
+ def output_config
203
+ return unless adaptive_thinking?
204
+
205
+ effort = @options.dig(:thinking, :effort)
206
+ { effort: } if effort
207
+ end
180
208
  end
181
209
  end
182
210
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OmniAI
4
4
  module Anthropic
5
- VERSION = "3.1.1"
5
+ VERSION = "3.2.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniai-anthropic
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Sylvestre