Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit 0fc854d

Browse files
committed
DEV: add subject
1 parent a0c0139 commit 0fc854d

File tree

8 files changed

+193
-211
lines changed

8 files changed

+193
-211
lines changed

app/controllers/discourse_ai/admin/ai_embeddings_controller.rb

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ def destroy
8585
embedding_id: embedding_def.id,
8686
display_name: embedding_def.display_name,
8787
provider: embedding_def.provider,
88-
dimensions: embedding_def.dimensions
88+
dimensions: embedding_def.dimensions,
89+
subject: embedding_def.display_name # Use display_name as the subject for EmbeddingDefinition
8990
}
9091

9192
if embedding_def.destroy
@@ -149,7 +150,8 @@ def log_ai_embedding_creation(embedding_def)
149150
embedding_id: embedding_def.id,
150151
display_name: embedding_def.display_name,
151152
provider: embedding_def.provider,
152-
dimensions: embedding_def.dimensions
153+
dimensions: embedding_def.dimensions,
154+
subject: embedding_def.display_name # Use display_name as the subject for EmbeddingDefinition
153155
}
154156

155157
# Only include tokenizer if present
@@ -162,6 +164,9 @@ def log_ai_embedding_creation(embedding_def)
162164
log_details[:api_key_set] = true
163165
end
164166

167+
# Get subject for the log
168+
subject = log_details[:subject]
169+
165170
# Log the action
166171
StaffActionLogger.new(current_user).log_custom("create_ai_embedding", log_details)
167172
end
@@ -170,7 +175,8 @@ def log_ai_embedding_update(embedding_def, initial_attributes)
170175
# Create log details
171176
log_details = {
172177
embedding_id: embedding_def.id,
173-
display_name: embedding_def.display_name
178+
display_name: embedding_def.display_name,
179+
subject: embedding_def.display_name # Use display_name as the subject for EmbeddingDefinition
174180
}
175181

176182
# Track changes in fields
@@ -204,11 +210,20 @@ def log_ai_embedding_update(embedding_def, initial_attributes)
204210
# Only log if there are actual changes
205211
if changed_fields.any?
206212
log_details[:changed_fields] = changed_fields
213+
214+
# Get subject for the log
215+
subject = log_details[:subject]
216+
217+
# Log the action
207218
StaffActionLogger.new(current_user).log_custom("update_ai_embedding", log_details)
208219
end
209220
end
210221

211222
def log_ai_embedding_deletion(embedding_details)
223+
# Get subject for the log (but keep it in the details hash)
224+
subject = embedding_details[:subject]
225+
226+
# Log the action
212227
StaffActionLogger.new(current_user).log_custom("delete_ai_embedding", embedding_details)
213228
end
214229
end

app/controllers/discourse_ai/admin/ai_llms_controller.rb

Lines changed: 56 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -207,101 +207,96 @@ def ai_llm_params(updating: nil)
207207
end
208208

209209
def log_llm_model_creation(llm_model)
210-
# Create field configuration with appropriate types
211-
field_config = {
212-
display_name: {},
213-
name: {},
214-
provider: {},
215-
tokenizer: {},
216-
url: {},
217-
api_key: { type: :sensitive },
218-
max_prompt_tokens: {},
219-
max_output_tokens: {},
220-
enabled_chat_bot: {},
221-
vision_enabled: {},
222-
input_cost: {},
223-
output_cost: {},
224-
cached_input_cost: {},
225-
provider_params: {}
226-
}
227-
228-
# Create basic entity details
229-
entity_details = {
210+
# Create basic entity details with important attributes
211+
log_details = {
230212
model_id: llm_model.id,
231213
model_name: llm_model.name,
232-
display_name: llm_model.display_name
214+
display_name: llm_model.display_name,
215+
provider: llm_model.provider,
216+
tokenizer: llm_model.tokenizer
233217
}
234218

235-
# Create logger instance
236-
logger = DiscourseAi::Utils::AiStaffActionLogger.new(current_user)
237-
238-
# Extract attributes based on field configuration
239-
log_details = entity_details.dup
240-
log_details.merge!(logger.send(:extract_entity_attributes, llm_model, field_config))
219+
# Add API key indication if present (without showing the key)
220+
if llm_model.api_key.present?
221+
log_details[:api_key_set] = true
222+
end
223+
224+
# Add token limits if set
225+
if llm_model.max_prompt_tokens.present?
226+
log_details[:max_prompt_tokens] = llm_model.max_prompt_tokens
227+
end
241228

229+
if llm_model.max_output_tokens.present?
230+
log_details[:max_output_tokens] = llm_model.max_output_tokens
231+
end
232+
242233
# Add quota information as a special case
243234
if llm_model.llm_quotas.any?
244235
log_details[:quotas] = llm_model.llm_quotas.map do |quota|
245236
"Group #{quota.group_id}: #{quota.max_tokens} tokens, #{quota.max_usages} usages, #{quota.duration_seconds}s"
246237
end.join("; ")
247238
end
248239

249-
logger.log_custom("create_ai_llm_model", log_details)
240+
# Use StaffActionLogger directly with the proper subject
241+
StaffActionLogger.new(current_user).log_custom("create_ai_llm_model", log_details.merge(subject: llm_model.display_name))
250242
end
251243

252244
def log_llm_model_update(llm_model, initial_attributes, initial_quotas)
253-
# Create field configuration with appropriate types
254-
field_config = {
255-
display_name: {},
256-
name: {},
257-
provider: {},
258-
tokenizer: {},
259-
url: {},
260-
api_key: { type: :sensitive },
261-
max_prompt_tokens: {},
262-
max_output_tokens: {},
263-
enabled_chat_bot: {},
264-
vision_enabled: {},
265-
input_cost: {},
266-
output_cost: {},
267-
cached_input_cost: {},
268-
provider_params: {},
269-
json_fields: %w[provider_params]
270-
}
271-
272245
# Create basic entity details
273-
entity_details = {
246+
log_details = {
274247
model_id: llm_model.id,
275248
model_name: llm_model.name,
276249
display_name: llm_model.display_name
277250
}
278251

279-
# Create logger instance
280-
logger = DiscourseAi::Utils::AiStaffActionLogger.new(current_user)
252+
# Track simple changes
253+
%w[display_name name provider tokenizer url max_prompt_tokens max_output_tokens enabled_chat_bot vision_enabled].each do |field|
254+
if initial_attributes[field] != llm_model.attributes[field]
255+
log_details["#{field}_changed"] = true
256+
257+
# For simple fields, show the before/after values
258+
unless field == "api_key" # Skip sensitive fields
259+
initial_value = initial_attributes[field]
260+
current_value = llm_model.attributes[field]
261+
log_details[field] = "#{initial_value}#{current_value}"
262+
end
263+
end
264+
end
281265

282-
# Create a changes hash to track all changes
283-
changes = {}
284-
current_quotas = llm_model.llm_quotas.reload.map(&:attributes)
266+
# Handle API key changes specially
267+
if initial_attributes["api_key"].present? != llm_model.api_key.present?
268+
log_details[:api_key_changed] = true
269+
if llm_model.api_key.present?
270+
log_details[:api_key_status] = "set"
271+
else
272+
log_details[:api_key_status] = "removed"
273+
end
274+
end
285275

286276
# Track quota changes separately as they're a special case
277+
current_quotas = llm_model.llm_quotas.reload.map(&:attributes)
287278
if initial_quotas != current_quotas
288279
initial_quota_summary = initial_quotas.map { |q| "Group #{q['group_id']}: #{q['max_tokens']} tokens" }.join("; ")
289280
current_quota_summary = current_quotas.map { |q| "Group #{q['group_id']}: #{q['max_tokens']} tokens" }.join("; ")
290-
changes[:quotas] = "#{initial_quota_summary}#{current_quota_summary}"
281+
log_details[:quotas_changed] = true
282+
log_details[:quotas] = "#{initial_quota_summary}#{current_quota_summary}"
291283
end
292284

293-
# Let the logger handle standard field changes
294-
logger.log_update("llm_model", llm_model, initial_attributes, field_config, entity_details)
285+
# Check JSON fields like provider_params
286+
if initial_attributes["provider_params"].to_s != llm_model.attributes["provider_params"].to_s
287+
log_details[:provider_params_changed] = true
288+
end
295289

296-
# If we have quota changes but no other changes were detected, log them separately
297-
if changes.key?(:quotas)
298-
logger.log_custom("update_ai_llm_model", entity_details.merge(changes))
290+
# Only log if there are actual changes
291+
if log_details.keys.any? { |k| k.to_s.end_with?("_changed") }
292+
# Use StaffActionLogger directly with the proper subject
293+
StaffActionLogger.new(current_user).log_custom("update_ai_llm_model", log_details.merge(subject: llm_model.display_name))
299294
end
300295
end
301296

302297
def log_llm_model_deletion(model_details)
303-
logger = DiscourseAi::Utils::AiStaffActionLogger.new(current_user)
304-
logger.log_deletion("llm_model", model_details)
298+
# Use StaffActionLogger directly with the proper subject
299+
StaffActionLogger.new(current_user).log_custom("delete_ai_llm_model", model_details.merge(subject: model_details[:display_name]))
305300
end
306301
end
307302
end

app/controllers/discourse_ai/admin/ai_personas_controller.rb

Lines changed: 55 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -276,98 +276,83 @@ def permit_examples(examples)
276276
end
277277

278278
def log_ai_persona_creation(ai_persona)
279-
# Create field configuration with appropriate types
280-
field_config = {
281-
name: {},
282-
description: {},
283-
enabled: {},
284-
priority: {},
285-
system_prompt: { type: :large_text },
286-
default_llm_id: {},
287-
temperature: {},
288-
top_p: {},
289-
user_id: {},
290-
vision_enabled: {},
291-
vision_max_pixels: {},
292-
max_context_posts: {},
293-
rag_chunk_tokens: {},
294-
rag_chunk_overlap_tokens: {},
295-
rag_conversation_chunks: {},
296-
rag_llm_model_id: {},
297-
question_consolidator_llm_id: {},
298-
tool_details: {},
299-
forced_tool_count: {},
300-
allow_chat_channel_mentions: {},
301-
allow_chat_direct_messages: {},
302-
allow_topic_mentions: {},
303-
allow_personal_messages: {}
304-
}
305-
306-
# Create basic entity details
307-
entity_details = {
279+
# Create basic entity details with important attributes
280+
log_details = {
308281
persona_id: ai_persona.id,
309-
persona_name: ai_persona.name
282+
persona_name: ai_persona.name,
283+
description: ai_persona.description
310284
}
311285

312-
# Create logger instance
313-
logger = DiscourseAi::Utils::AiStaffActionLogger.new(current_user)
286+
# Include basic configuration fields if present
287+
%w[enabled priority temperature top_p default_llm_id].each do |field|
288+
value = ai_persona.send(field) if ai_persona.respond_to?(field)
289+
log_details[field] = value if value.present?
290+
end
314291

315-
# Extract attributes based on field configuration
316-
log_details = entity_details.dup
317-
log_details.merge!(logger.send(:extract_entity_attributes, ai_persona, field_config))
292+
# Handle system prompt specially (truncate if too long)
293+
if ai_persona.system_prompt.present?
294+
if ai_persona.system_prompt.length > 100
295+
log_details[:system_prompt] = ai_persona.system_prompt.truncate(100)
296+
else
297+
log_details[:system_prompt] = ai_persona.system_prompt
298+
end
299+
end
318300

319301
# Add tools count separately as it's not a direct attribute
320302
log_details[:tools_count] = (ai_persona.tools || []).size
321303

322304
# Add allowed_group_ids
323305
log_details[:allowed_group_ids] = ai_persona.allowed_group_ids if ai_persona.allowed_group_ids.present?
324306

325-
logger.log_custom("create_ai_persona", log_details)
307+
# Use StaffActionLogger directly with the proper subject
308+
StaffActionLogger.new(current_user).log_custom("create_ai_persona", log_details.merge(subject: ai_persona.name))
326309
end
327310

328311
def log_ai_persona_update(ai_persona, initial_attributes)
329-
# Create field configuration with appropriate types
330-
field_config = {
331-
name: {},
332-
description: {},
333-
enabled: {},
334-
priority: {},
335-
system_prompt: { type: :large_text },
336-
default_llm_id: {},
337-
temperature: {},
338-
top_p: {},
339-
user_id: {},
340-
vision_enabled: {},
341-
vision_max_pixels: {},
342-
max_context_posts: {},
343-
rag_chunk_tokens: {},
344-
rag_chunk_overlap_tokens: {},
345-
rag_conversation_chunks: {},
346-
rag_llm_model_id: {},
347-
question_consolidator_llm_id: {},
348-
tool_details: {},
349-
forced_tool_count: {},
350-
allow_chat_channel_mentions: {},
351-
allow_chat_direct_messages: {},
352-
allow_topic_mentions: {},
353-
allow_personal_messages: {},
354-
json_fields: %w[allowed_group_ids tools response_format examples]
355-
}
356-
357312
# Create basic entity details
358-
entity_details = {
313+
log_details = {
359314
persona_id: ai_persona.id,
360315
persona_name: ai_persona.name
361316
}
362317

363-
# Create logger instance and log the update
364-
logger = DiscourseAi::Utils::AiStaffActionLogger.new(current_user)
365-
logger.log_update("persona", ai_persona, initial_attributes, field_config, entity_details)
318+
# Track simple changes
319+
%w[name description enabled priority system_prompt default_llm_id temperature top_p
320+
vision_enabled vision_max_pixels max_context_posts rag_chunk_tokens rag_chunk_overlap_tokens
321+
rag_conversation_chunks rag_llm_model_id question_consolidator_llm_id forced_tool_count
322+
allow_chat_channel_mentions allow_chat_direct_messages allow_topic_mentions allow_personal_messages].each do |field|
323+
324+
if initial_attributes[field] != ai_persona.attributes[field]
325+
log_details["#{field}_changed"] = true
326+
327+
# For large text fields, don't include the values
328+
if field == "system_prompt"
329+
log_details["#{field}_updated"] = true
330+
else
331+
# For simple fields, show the before/after values
332+
initial_value = initial_attributes[field]
333+
current_value = ai_persona.attributes[field]
334+
log_details[field] = "#{initial_value}#{current_value}"
335+
end
336+
end
337+
end
338+
339+
# Check JSON fields
340+
%w[allowed_group_ids tools response_format examples].each do |field|
341+
if initial_attributes[field].to_s != ai_persona.attributes[field].to_s
342+
log_details["#{field}_changed"] = true
343+
end
344+
end
345+
346+
# Only log if there are actual changes
347+
if log_details.keys.any? { |k| k.to_s.end_with?("_changed") }
348+
# Use StaffActionLogger directly with the proper subject
349+
StaffActionLogger.new(current_user).log_custom("update_ai_persona", log_details.merge(subject: ai_persona.name))
350+
end
366351
end
367352

368353
def log_ai_persona_deletion(persona_details)
369-
logger = DiscourseAi::Utils::AiStaffActionLogger.new(current_user)
370-
logger.log_deletion("persona", persona_details)
354+
# Use StaffActionLogger directly with the proper subject
355+
StaffActionLogger.new(current_user).log_custom("delete_ai_persona", persona_details.merge(subject: persona_details[:name]))
371356
end
372357
end
373358
end

0 commit comments

Comments
 (0)