diff --git a/sentry-agents/README.md b/sentry-agents/README.md index e6a0457e9..b6c031434 100644 --- a/sentry-agents/README.md +++ b/sentry-agents/README.md @@ -16,3 +16,16 @@ Add the gem to your bundle: ```ruby gem "sentry-agents" ``` + +## GenAI data collection + +Configure prompt and completion content independently: + +```ruby +Sentry.init do |config| + config.data_collection.gen_ai.inputs = true + config.data_collection.gen_ai.outputs = false +end +``` + +These settings only control GenAI content. HTTP body, breadcrumb, and exception-local collection have separate controls; disabling GenAI content is not a blanket redaction switch. diff --git a/sentry-ruby/lib/sentry/data_collection.rb b/sentry-ruby/lib/sentry/data_collection.rb index 499447d64..e0f5d2cea 100644 --- a/sentry-ruby/lib/sentry/data_collection.rb +++ b/sentry-ruby/lib/sentry/data_collection.rb @@ -74,6 +74,19 @@ def initialize(document:, variables:) end end + class GenAI + # @return [Boolean] + attr_accessor :inputs + + # @return [Boolean] + attr_accessor :outputs + + def initialize(inputs:, outputs:) + @inputs = inputs + @outputs = outputs + end + end + # @return [Boolean] # @default `true` attr_accessor :user_info @@ -104,6 +117,10 @@ def initialize(document:, variables:) # @default `document: true, variables: true` attr_accessor :graphql + # @return [GenAI] + # @default `inputs: true, outputs: true` + attr_accessor :gen_ai + # @return [Boolean] # @default `true` attr_accessor :queues @@ -145,6 +162,8 @@ def self.backfill(configuration) data_collection.url_query_params.mode = :off data_collection.graphql.document = false data_collection.graphql.variables = false + data_collection.gen_ai.inputs = false + data_collection.gen_ai.outputs = false data_collection.database_query_data = false data_collection.queues = false data_collection @@ -161,6 +180,7 @@ def initialize self.url_query_params = KeyValueCollection.new(mode: :deny_list, terms: nil) @database_query_data = true @graphql = GraphQL.new(document: true, variables: true) + @gen_ai = GenAI.new(inputs: true, outputs: true) @queues = true self.stack_frame_variables = false @frame_context_lines = 3 diff --git a/sentry-ruby/spec/sentry/configuration_spec.rb b/sentry-ruby/spec/sentry/configuration_spec.rb index 8743bcded..c0efc90eb 100644 --- a/sentry-ruby/spec/sentry/configuration_spec.rb +++ b/sentry-ruby/spec/sentry/configuration_spec.rb @@ -11,6 +11,17 @@ expect(configuration.data_collection.user_info).to eq(false) end + it "allows explicit GenAI configuration after send_default_pii backfill" do + configuration = Sentry::Configuration.new do |config| + config.send_default_pii = false + config.data_collection.gen_ai.inputs = true + config.data_collection.gen_ai.outputs = false + end + + expect(configuration.data_collection.gen_ai.inputs).to eq(true) + expect(configuration.data_collection.gen_ai.outputs).to eq(false) + end + it "falls back to include_local_variables for stack frame variables" do configuration = Sentry::Configuration.new do |config| config.include_local_variables = true diff --git a/sentry-ruby/spec/sentry/data_collection_spec.rb b/sentry-ruby/spec/sentry/data_collection_spec.rb index 8ddf5a92d..b20d22ae8 100644 --- a/sentry-ruby/spec/sentry/data_collection_spec.rb +++ b/sentry-ruby/spec/sentry/data_collection_spec.rb @@ -28,6 +28,8 @@ expect(data_collection.database_query_data).to eq(false) expect(data_collection.graphql.document).to eq(false) expect(data_collection.graphql.variables).to eq(false) + expect(data_collection.gen_ai.inputs).to eq(false) + expect(data_collection.gen_ai.outputs).to eq(false) expect(data_collection.queues).to eq(false) expect(data_collection.stack_frame_variables.mode).to eq(:off) expect(data_collection.frame_context_lines).to eq(3) @@ -84,6 +86,8 @@ expect(data_collection.database_query_data).to eq(true) expect(data_collection.graphql.document).to eq(true) expect(data_collection.graphql.variables).to eq(true) + expect(data_collection.gen_ai.inputs).to eq(true) + expect(data_collection.gen_ai.outputs).to eq(true) expect(data_collection.queues).to eq(true) expect(data_collection.stack_frame_variables.mode).to eq(:off) expect(data_collection.frame_context_lines).to eq(3) @@ -155,5 +159,15 @@ expect(data_collection.graphql.document).to eq(false) expect(data_collection.graphql.variables).to eq(false) end + + [[true, true], [true, false], [false, true], [false, false]].each do |inputs, outputs| + it "supports configuring GenAI inputs=#{inputs} and outputs=#{outputs}" do + data_collection.gen_ai.inputs = inputs + data_collection.gen_ai.outputs = outputs + + expect(data_collection.gen_ai.inputs).to eq(inputs) + expect(data_collection.gen_ai.outputs).to eq(outputs) + end + end end end