ask-agent 0.3.0 → 0.3.1

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: 4812b86203eb5a12eb03138de1e50fe8f0a80532f545bb683dcf051f2729c088
4
- data.tar.gz: ba9e999b2aedae3e9c0f55067a35e3d3f29f828717a8f7129c0e0037bd518a33
3
+ metadata.gz: 26c124febbf2652616754dd539cc8df5d24afe5fbe8c03381f760598578a051f
4
+ data.tar.gz: 50d87794d60901a85da426f50a1a619807faf96bbe1fedb58145dd2d5d7fbeb1
5
5
  SHA512:
6
- metadata.gz: a5b049b05acf1a82334a2169a708d60a6511db2d790ec5db3f30b9b4775a561eb204b8fdb209b60d095edeba43bd27f1572a909d78118eba9f295943625da370
7
- data.tar.gz: 54ba99bbacd6152c52196f276f28559d2a13e09b048338c4c5198e9ab01c8f2cc9e5eb57c2a957b1ba6dea4410726c3eba644104b66d767729e908a10c366133
6
+ metadata.gz: 5927098dcbd1fe84faa0cf2a7cddbc63e544a7113e47c61f972044e598053758417edce0e63d9a55d7922fbbc65ad9f552ef5c3fb1c07ac71ba1b718d1cbb815
7
+ data.tar.gz: 0436ac54f1dcd57ac06706d7e6a8ad5030574341170e0c7e99ca174d3dd94341651142c78bf5d138be1f99a978d71eb21f03a57df1ef4b6cb038ebb22778a637
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## [0.3.1] — 2026-07-17
2
+
3
+ ### Added
4
+
5
+ - **Rate-limit aware retry in Chat** — `Chat#ask` retries up to 3 times on `RateLimitError`, using `retry_after` from the error when available, otherwise exponential backoff with jitter.
6
+
7
+ ### Fixed
8
+
9
+ - **`retryable_error_name?` in ToolExecutor** — fixed duplicate `Ask::RateLimitError` and non-existent `Ask::ServiceUnavailableError`. Now uses class hierarchy matching so subclasses are also retried. (Backport from LiteLLM error classification.)
10
+
1
11
  ## [0.3.0] — 2026-07-17
2
12
 
3
13
  ### Added
@@ -49,27 +49,7 @@ module Ask
49
49
  provider_schema = @schema&.respond_to?(:to_json_schema) ? @schema.to_json_schema : @schema
50
50
  provider_params = @extra_params || {}
51
51
 
52
- result = provider.chat(
53
- @messages.map(&:to_h),
54
- model: provider_model,
55
- tools: provider_tools,
56
- temperature: provider_temp,
57
- stream: stream,
58
- schema: provider_schema,
59
- **provider_params
60
- ) do |raw_chunk|
61
- next unless block_given?
62
-
63
- accumulate_tool_calls(raw_chunk, calls_acc)
64
-
65
- yield ChatChunk.new(
66
- content: raw_chunk.content,
67
- tool_calls: build_current_tool_calls(calls_acc),
68
- thinking: raw_chunk.respond_to?(:thinking) ? raw_chunk.thinking : nil,
69
- input_tokens: nil,
70
- output_tokens: nil
71
- )
72
- end
52
+ result = chat_with_retry(stream, calls_acc, &block)
73
53
 
74
54
  response_msg = if stream
75
55
  build_stream_response(result, calls_acc)
@@ -234,6 +214,41 @@ module Ask
234
214
  nil
235
215
  end
236
216
 
217
+ MAX_CHAT_RETRIES = 3
218
+
219
+ def chat_with_retry(stream, calls_acc, &block)
220
+ MAX_CHAT_RETRIES.times do |attempt|
221
+ begin
222
+ return provider.chat(
223
+ @messages.map(&:to_h),
224
+ model: @model_id,
225
+ tools: @tools.map { |t| Ask::ToolDef.from_tool(t) },
226
+ temperature: @temperature,
227
+ stream: stream,
228
+ schema: @schema&.respond_to?(:to_json_schema) ? @schema.to_json_schema : @schema,
229
+ **(@extra_params || {})
230
+ ) do |raw_chunk|
231
+ next unless block
232
+
233
+ accumulate_tool_calls(raw_chunk, calls_acc)
234
+
235
+ block.call(ChatChunk.new(
236
+ content: raw_chunk.content,
237
+ tool_calls: build_current_tool_calls(calls_acc),
238
+ thinking: raw_chunk.respond_to?(:thinking) ? raw_chunk.thinking : nil,
239
+ input_tokens: nil,
240
+ output_tokens: nil
241
+ ))
242
+ end
243
+ rescue Ask::RateLimitError => e
244
+ raise if attempt >= MAX_CHAT_RETRIES - 1
245
+
246
+ delay = e.retry_after || ((2 ** attempt) + rand(0.0..1.0))
247
+ sleep(delay)
248
+ end
249
+ end
250
+ end
251
+
237
252
  def emit_instrumentation(stream, response_msg)
238
253
  return unless defined?(Ask::Instrumentation)
239
254
 
@@ -182,10 +182,15 @@ module Ask
182
182
  end
183
183
 
184
184
  def retryable_error_name?(error_name)
185
- retryable = %w[Timeout::Error Errno::ETIMEDOUT
186
- Ask::RateLimitError Ask::ServerError
187
- Ask::RateLimitError Ask::ServiceUnavailableError]
188
- retryable.include?(error_name)
185
+ return false unless error_name
186
+
187
+ klass = Object.const_get(error_name) rescue nil
188
+ return false unless klass
189
+
190
+ klass <= Ask::RateLimitError ||
191
+ klass <= Ask::ServerError ||
192
+ klass <= Ask::ServiceUnavailable ||
193
+ %w[Timeout::Error Errno::ETIMEDOUT].include?(error_name)
189
194
  end
190
195
 
191
196
  def critical_error?(error_class_name)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ask
4
4
  module Agent
5
- VERSION = "0.3.0"
5
+ VERSION = "0.3.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto