From e271c0f690cf29e6de2210160686c9f1de10837b Mon Sep 17 00:00:00 2001 From: Nina Revko Date: Thu, 21 Aug 2025 17:47:59 -0700 Subject: [PATCH 1/5] Adding custom configuration for Regexp timeout for logging --- lib/ruby_llm/configuration.rb | 4 +++- spec/ruby_llm/context_spec.rb | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/ruby_llm/configuration.rb b/lib/ruby_llm/configuration.rb index 6715817a6..77a32a24e 100644 --- a/lib/ruby_llm/configuration.rb +++ b/lib/ruby_llm/configuration.rb @@ -36,7 +36,8 @@ class Configuration :logger, :log_file, :log_level, - :log_stream_debug + :log_stream_debug, + :log_regexp_timeout def initialize @request_timeout = 120 @@ -53,6 +54,7 @@ def initialize @log_file = $stdout @log_level = ENV['RUBYLLM_DEBUG'] ? Logger::DEBUG : Logger::INFO @log_stream_debug = ENV['RUBYLLM_STREAM_DEBUG'] == 'true' + @log_regexp_timeout = Regexp.timeout end def instance_variables diff --git a/spec/ruby_llm/context_spec.rb b/spec/ruby_llm/context_spec.rb index 2bbb25626..a05c8a6fd 100644 --- a/spec/ruby_llm/context_spec.rb +++ b/spec/ruby_llm/context_spec.rb @@ -10,20 +10,24 @@ # Get current config values original_model = RubyLLM.config.default_model original_api_key = RubyLLM.config.openai_api_key + original_log_regexp_timeout = RubyLLM.config.log_regexp_timeout # Create context with modified config context = RubyLLM.context do |config| config.default_model = 'modified-model' config.openai_api_key = 'modified-key' + config.log_regexp_timeout = 5.0 end # Verify global config is unchanged expect(RubyLLM.config.default_model).to eq(original_model) expect(RubyLLM.config.openai_api_key).to eq(original_api_key) + expect(RubyLLM.config.log_regexp_timeout).to eq(original_log_regexp_timeout) # Verify context has modified config expect(context.config.default_model).to eq('modified-model') expect(context.config.openai_api_key).to eq('modified-key') + expect(context.config.log_regexp_timeout).to eq(5.0) end end @@ -95,6 +99,7 @@ it 'allows multiple contexts with different configurations' do context1 = RubyLLM.context do |config| config.default_model = 'gpt-4.1-nano' + config.log_regexp_timeout = 5.0 end context2 = RubyLLM.context do |config| @@ -105,7 +110,11 @@ chat2 = context2.chat expect(chat1.model.id).to eq('gpt-4.1-nano') + expect(context1.config.log_regexp_timeout).not_to eq(Regexp.timeout) + expect(context1.config.log_regexp_timeout).to eq(5.0) + expect(chat2.model.id).to eq('claude-3-5-haiku-20241022') + expect(context2.config.log_regexp_timeout).to eq(Regexp.timeout) end it 'ensures changes in one context do not affect another' do From 42434b901e2cff7d57e53cda114bbea4bd24f2b4 Mon Sep 17 00:00:00 2001 From: Nina Revko Date: Thu, 21 Aug 2025 17:49:25 -0700 Subject: [PATCH 2/5] Updating logging filters to utilize custom Regexp timeout --- lib/ruby_llm/connection.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ruby_llm/connection.rb b/lib/ruby_llm/connection.rb index 32d888f00..15dc7c562 100644 --- a/lib/ruby_llm/connection.rb +++ b/lib/ruby_llm/connection.rb @@ -62,8 +62,8 @@ def setup_logging(faraday) errors: true, headers: false, log_level: :debug do |logger| - logger.filter(%r{[A-Za-z0-9+/=]{100,}}, 'data":"[BASE64 DATA]"') - logger.filter(/[-\d.e,\s]{100,}/, '[EMBEDDINGS ARRAY]') + logger.filter(Regexp.new('[A-Za-z0-9+/=]{100,}', timeout: @config.log_regexp_timeout), 'data":"[BASE64 DATA]"') + logger.filter(Regexp.new('[-\\d.e,\\s]{100,}', timeout: @config.log_regexp_timeout), '[EMBEDDINGS ARRAY]') end end From 287b09441210eefb1f516dbad8f4a88675f04666 Mon Sep 17 00:00:00 2001 From: Nina Revko Date: Thu, 21 Aug 2025 18:08:45 -0700 Subject: [PATCH 3/5] Updating documentation with log_regexp_timeout config option --- docs/_getting_started/configuration.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/_getting_started/configuration.md b/docs/_getting_started/configuration.md index 3c9d6b8ce..67650cb7a 100644 --- a/docs/_getting_started/configuration.md +++ b/docs/_getting_started/configuration.md @@ -204,6 +204,10 @@ RubyLLM.configure do |config| # Or use Rails logger config.logger = Rails.logger # Overrides log_file and log_level + + # Set custom timeout for log filtering + # which is useful when working with large payloads + config.log_regexp_timeout = 4 # seconds end ``` @@ -354,6 +358,7 @@ RubyLLM.configure do |config| config.log_file = String config.log_level = Symbol config.log_stream_debug = Boolean # v1.6.0+ + config.log_regexp_timeout = Integer # v1.6.5+ end ``` @@ -363,4 +368,4 @@ Now that you've configured RubyLLM, you're ready to: - [Start chatting with AI models]({% link _core_features/chat.md %}) - [Work with different providers and models]({% link _advanced/models.md %}) -- [Set up Rails integration]({% link _advanced/rails.md %}) \ No newline at end of file +- [Set up Rails integration]({% link _advanced/rails.md %}) From 838ad403bb99c539315a20ed1080cf8ebd019845 Mon Sep 17 00:00:00 2001 From: Nina Revko Date: Fri, 5 Sep 2025 17:28:28 -0700 Subject: [PATCH 4/5] make log_regexp_timeout config compatible w/ruby 3.1.3 --- lib/ruby_llm/configuration.rb | 2 +- lib/ruby_llm/connection.rb | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/ruby_llm/configuration.rb b/lib/ruby_llm/configuration.rb index 77a32a24e..d55da7380 100644 --- a/lib/ruby_llm/configuration.rb +++ b/lib/ruby_llm/configuration.rb @@ -54,7 +54,7 @@ def initialize @log_file = $stdout @log_level = ENV['RUBYLLM_DEBUG'] ? Logger::DEBUG : Logger::INFO @log_stream_debug = ENV['RUBYLLM_STREAM_DEBUG'] == 'true' - @log_regexp_timeout = Regexp.timeout + @log_regexp_timeout = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2.0') ? Regexp.timeout : nil end def instance_variables diff --git a/lib/ruby_llm/connection.rb b/lib/ruby_llm/connection.rb index 15dc7c562..a8fb75bea 100644 --- a/lib/ruby_llm/connection.rb +++ b/lib/ruby_llm/connection.rb @@ -62,8 +62,19 @@ def setup_logging(faraday) errors: true, headers: false, log_level: :debug do |logger| - logger.filter(Regexp.new('[A-Za-z0-9+/=]{100,}', timeout: @config.log_regexp_timeout), 'data":"[BASE64 DATA]"') - logger.filter(Regexp.new('[-\\d.e,\\s]{100,}', timeout: @config.log_regexp_timeout), '[EMBEDDINGS ARRAY]') + if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2.0') + logger.filter( + Regexp.new('[A-Za-z0-9+/=]{100,}', timeout: @config.log_regexp_timeout), + 'data":"[BASE64 DATA]"' + ) + logger.filter(Regexp.new('[-\\d.e,\\s]{100,}', timeout: @config.log_regexp_timeout), '[EMBEDDINGS ARRAY]') + else + if @config.log_regexp_timeout + RubyLLM.logger.warn("log_regexp_timeout is not supported on Ruby #{RUBY_VERSION}") + end + logger.filter(Regexp.new('[A-Za-z0-9+/=]{100,}'), 'data":"[BASE64 DATA]"') + logger.filter(Regexp.new('[-\\d.e,\\s]{100,}'), '[EMBEDDINGS ARRAY]') + end end end From dbae501be099e64a3a61ef680224be0ce2600256 Mon Sep 17 00:00:00 2001 From: Nina Revko Date: Fri, 5 Sep 2025 18:46:19 -0700 Subject: [PATCH 5/5] Defauting log_regexp_timeout to 1s if Regexp.timeout is nil --- lib/ruby_llm/configuration.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ruby_llm/configuration.rb b/lib/ruby_llm/configuration.rb index 2391f1ca3..f78a73676 100644 --- a/lib/ruby_llm/configuration.rb +++ b/lib/ruby_llm/configuration.rb @@ -58,7 +58,7 @@ def initialize @log_file = $stdout @log_level = ENV['RUBYLLM_DEBUG'] ? Logger::DEBUG : Logger::INFO @log_stream_debug = ENV['RUBYLLM_STREAM_DEBUG'] == 'true' - @log_regexp_timeout = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2.0') ? Regexp.timeout : nil + @log_regexp_timeout = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2.0') ? (Regexp.timeout || 1.0) : nil end def instance_variables