DEV: doc style comments + i18n.t()
This commit is contained in:
parent
9a69cb8796
commit
46e13f200f
|
@ -586,6 +586,11 @@ en:
|
||||||
missing_provider_param: "%{param} can't be blank"
|
missing_provider_param: "%{param} can't be blank"
|
||||||
bedrock_invalid_url: "Please complete all the fields to use this model."
|
bedrock_invalid_url: "Please complete all the fields to use this model."
|
||||||
|
|
||||||
|
ai_staff_action_logger:
|
||||||
|
updated: "updated"
|
||||||
|
set: "set"
|
||||||
|
removed: "removed"
|
||||||
|
|
||||||
errors:
|
errors:
|
||||||
quota_exceeded: "You have exceeded the quota for this model. Please try again in %{relative_time}."
|
quota_exceeded: "You have exceeded the quota for this model. Please try again in %{relative_time}."
|
||||||
quota_required: "You must specify maximum tokens or usages for this model"
|
quota_required: "You must specify maximum tokens or usages for this model"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
module DiscourseAi
|
module DiscourseAi
|
||||||
module Utils
|
module Utils
|
||||||
class AiStaffActionLogger
|
class AiStaffActionLogger
|
||||||
# Maximum length for text fields before truncation/simplification
|
## Maximum length for text fields before truncation/simplification
|
||||||
MAX_TEXT_LENGTH = 100
|
MAX_TEXT_LENGTH = 100
|
||||||
|
|
||||||
def initialize(current_user)
|
def initialize(current_user)
|
||||||
|
@ -11,15 +11,21 @@ module DiscourseAi
|
||||||
@staff_logger = ::StaffActionLogger.new(current_user)
|
@staff_logger = ::StaffActionLogger.new(current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Log creation of an AI entity (LLM model or persona)
|
## Logs the creation of an AI entity (LLM model or persona)
|
||||||
|
## @param entity_type [Symbol] The type of AI entity being created
|
||||||
|
## @param entity [Object] The entity object being created
|
||||||
|
## @param field_config [Hash] Configuration for how to handle different entity fields
|
||||||
|
## @param entity_details [Hash] Additional details about the entity to be logged
|
||||||
def log_creation(entity_type, entity, field_config = {}, entity_details = {})
|
def log_creation(entity_type, entity, field_config = {}, entity_details = {})
|
||||||
# Start with provided entity details (id, name, etc.)
|
# Start with provided entity details (id, name, etc.)
|
||||||
# Convert all keys to strings for consistent handling in StaffActionLogger
|
# Convert all keys to strings for consistent handling in StaffActionLogger
|
||||||
log_details = {}
|
log_details = {}
|
||||||
|
|
||||||
# Extract subject for StaffActionLogger.base_attrs
|
# Extract subject for StaffActionLogger.base_attrs
|
||||||
subject = entity_details[:subject] || (entity.respond_to?(:display_name) ? entity.display_name : nil)
|
subject =
|
||||||
|
entity_details[:subject] ||
|
||||||
|
(entity.respond_to?(:display_name) ? entity.display_name : nil)
|
||||||
|
|
||||||
# Add the entity details but preserve subject as a top-level attribute
|
# Add the entity details but preserve subject as a top-level attribute
|
||||||
entity_details.each { |k, v| log_details[k.to_s] = v unless k == :subject }
|
entity_details.each { |k, v| log_details[k.to_s] = v unless k == :subject }
|
||||||
|
|
||||||
|
@ -31,7 +37,12 @@ module DiscourseAi
|
||||||
@staff_logger.log_custom("create_ai_#{entity_type}", log_details.merge(subject: subject))
|
@staff_logger.log_custom("create_ai_#{entity_type}", log_details.merge(subject: subject))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Log update of an AI entity with before/after comparison
|
## Logs an update to an AI entity with before/after comparison
|
||||||
|
## @param entity_type [Symbol] The type of AI entity being updated
|
||||||
|
## @param entity [Object] The entity object after update
|
||||||
|
## @param initial_attributes [Hash] The attributes of the entity before update
|
||||||
|
## @param field_config [Hash] Configuration for how to handle different entity fields
|
||||||
|
## @param entity_details [Hash] Additional details about the entity to be logged
|
||||||
def log_update(
|
def log_update(
|
||||||
entity_type,
|
entity_type,
|
||||||
entity,
|
entity,
|
||||||
|
@ -69,7 +80,7 @@ module DiscourseAi
|
||||||
field_config[:json_fields].each do |field|
|
field_config[:json_fields].each do |field|
|
||||||
field_str = field.to_s
|
field_str = field.to_s
|
||||||
if initial_attributes[field_str].to_s != current_attributes[field_str].to_s
|
if initial_attributes[field_str].to_s != current_attributes[field_str].to_s
|
||||||
changes[field_str] = "updated"
|
changes[field_str] = I18n.t("discourse_ai.ai_staff_action_logger.updated")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -77,8 +88,10 @@ module DiscourseAi
|
||||||
# Only log if there are actual changes
|
# Only log if there are actual changes
|
||||||
if changes.any?
|
if changes.any?
|
||||||
# Extract subject for StaffActionLogger.base_attrs
|
# Extract subject for StaffActionLogger.base_attrs
|
||||||
subject = entity_details[:subject] || (entity.respond_to?(:display_name) ? entity.display_name : nil)
|
subject =
|
||||||
|
entity_details[:subject] ||
|
||||||
|
(entity.respond_to?(:display_name) ? entity.display_name : nil)
|
||||||
|
|
||||||
log_details = {}
|
log_details = {}
|
||||||
# Convert entity_details keys to strings, but preserve subject as a top-level attribute
|
# Convert entity_details keys to strings, but preserve subject as a top-level attribute
|
||||||
entity_details.each { |k, v| log_details[k.to_s] = v unless k == :subject }
|
entity_details.each { |k, v| log_details[k.to_s] = v unless k == :subject }
|
||||||
|
@ -89,11 +102,13 @@ module DiscourseAi
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Log deletion of an AI entity
|
## Logs the deletion of an AI entity
|
||||||
|
## @param entity_type [Symbol] The type of AI entity being deleted
|
||||||
|
## @param entity_details [Hash] Details about the entity being deleted
|
||||||
def log_deletion(entity_type, entity_details)
|
def log_deletion(entity_type, entity_details)
|
||||||
# Extract subject for StaffActionLogger.base_attrs
|
# Extract subject for StaffActionLogger.base_attrs
|
||||||
subject = entity_details[:subject]
|
subject = entity_details[:subject]
|
||||||
|
|
||||||
# Convert all keys to strings for consistent handling in StaffActionLogger
|
# Convert all keys to strings for consistent handling in StaffActionLogger
|
||||||
string_details = {}
|
string_details = {}
|
||||||
entity_details.each { |k, v| string_details[k.to_s] = v unless k == :subject }
|
entity_details.each { |k, v| string_details[k.to_s] = v unless k == :subject }
|
||||||
|
@ -101,11 +116,13 @@ module DiscourseAi
|
||||||
@staff_logger.log_custom("delete_ai_#{entity_type}", string_details.merge(subject: subject))
|
@staff_logger.log_custom("delete_ai_#{entity_type}", string_details.merge(subject: subject))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Direct custom logging for complex cases
|
## Direct custom logging for complex cases
|
||||||
|
## @param action_type [String] The type of action being logged
|
||||||
|
## @param log_details [Hash] Details to be logged
|
||||||
def log_custom(action_type, log_details)
|
def log_custom(action_type, log_details)
|
||||||
# Extract subject for StaffActionLogger.base_attrs if present
|
# Extract subject for StaffActionLogger.base_attrs if present
|
||||||
subject = log_details[:subject]
|
subject = log_details[:subject]
|
||||||
|
|
||||||
# Convert all keys to strings for consistent handling in StaffActionLogger
|
# Convert all keys to strings for consistent handling in StaffActionLogger
|
||||||
string_details = {}
|
string_details = {}
|
||||||
log_details.each { |k, v| string_details[k.to_s] = v unless k == :subject }
|
log_details.each { |k, v| string_details[k.to_s] = v unless k == :subject }
|
||||||
|
@ -115,38 +132,49 @@ module DiscourseAi
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
## Formats the change in a field's value for logging
|
||||||
|
## @param field [Symbol] The field that changed
|
||||||
|
## @param initial_value [Object] The original value
|
||||||
|
## @param current_value [Object] The new value
|
||||||
|
## @param options [Hash] Options for formatting
|
||||||
|
## @return [String] Formatted representation of the change
|
||||||
def format_field_change(field, initial_value, current_value, options = {})
|
def format_field_change(field, initial_value, current_value, options = {})
|
||||||
# Handle different field types based on controller-provided options
|
|
||||||
if options[:type] == :sensitive
|
if options[:type] == :sensitive
|
||||||
return format_sensitive_field_change(initial_value, current_value)
|
return format_sensitive_field_change(initial_value, current_value)
|
||||||
elsif options[:type] == :large_text ||
|
elsif options[:type] == :large_text ||
|
||||||
(initial_value.is_a?(String) && initial_value.length > MAX_TEXT_LENGTH) ||
|
(initial_value.is_a?(String) && initial_value.length > MAX_TEXT_LENGTH) ||
|
||||||
(current_value.is_a?(String) && current_value.length > MAX_TEXT_LENGTH)
|
(current_value.is_a?(String) && current_value.length > MAX_TEXT_LENGTH)
|
||||||
return "updated"
|
return I18n.t("discourse_ai.ai_staff_action_logger.updated")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Default formatting: "old_value → new_value"
|
# Default formatting: "old_value → new_value"
|
||||||
"#{initial_value} → #{current_value}"
|
"#{initial_value} → #{current_value}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
## Formats changes to sensitive fields without exposing actual values
|
||||||
|
## @param initial_value [Object] The original value
|
||||||
|
## @param current_value [Object] The new value
|
||||||
|
## @return [String] Description of the change (updated/set/removed)
|
||||||
def format_sensitive_field_change(initial_value, current_value)
|
def format_sensitive_field_change(initial_value, current_value)
|
||||||
if initial_value.present? && current_value.present?
|
if initial_value.present? && current_value.present?
|
||||||
"updated"
|
I18n.t("discourse_ai.ai_staff_action_logger.updated")
|
||||||
elsif current_value.present?
|
elsif current_value.present?
|
||||||
"set"
|
I18n.t("discourse_ai.ai_staff_action_logger.set")
|
||||||
else
|
else
|
||||||
"removed"
|
I18n.t("discourse_ai.ai_staff_action_logger.removed")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
## Extracts relevant attributes from an entity based on field configuration
|
||||||
|
## @param entity [Object] The entity to extract attributes from
|
||||||
|
## @param field_config [Hash] Configuration for how to handle different entity fields
|
||||||
|
## @return [Hash] The extracted attributes
|
||||||
def extract_entity_attributes(entity, field_config)
|
def extract_entity_attributes(entity, field_config)
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
# Process each field according to its configuration
|
|
||||||
field_config.each do |field, options|
|
field_config.each do |field, options|
|
||||||
# Skip special keys like :json_fields which are arrays, not field configurations
|
# Skip special keys like :json_fields which are arrays, not field configurations
|
||||||
next if field == :json_fields
|
next if field == :json_fields
|
||||||
|
|
||||||
# Skip if options is not a hash or if explicitly marked as not to be extracted
|
# Skip if options is not a hash or if explicitly marked as not to be extracted
|
||||||
next if !options.is_a?(Hash) || options[:extract] == false
|
next if !options.is_a?(Hash) || options[:extract] == false
|
||||||
|
|
||||||
|
@ -164,7 +192,7 @@ module DiscourseAi
|
||||||
result[field] = value
|
result[field] = value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Always include dimensions if it exists on the entity
|
# Always include dimensions if it exists on the entity
|
||||||
# This is important for embeddings which are tested for dimensions value
|
# This is important for embeddings which are tested for dimensions value
|
||||||
if entity.respond_to?(:dimensions) && !result.key?(:dimensions)
|
if entity.respond_to?(:dimensions) && !result.key?(:dimensions)
|
||||||
|
|
Loading…
Reference in New Issue