8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
# File 'app/jobs/collavre/compress_job.rb', line 8
def perform(creative_id, topic_id, user_id, = nil)
creative = Creative.find(creative_id)
topic = Topic.find(topic_id)
user = User.find(user_id)
= creative.
.where(topic_id: topic_id)
.order(created_at: :asc)
.includes(:user, images_attachments: :blob)
compress_pattern = /\A\/compress\b/i
= .reject { |c| c.content.to_s.strip.match?(compress_pattern) }
return if .size < 2
conversation = .map do |c|
author = c.user&.name || I18n.t("collavre.comments.anonymous")
"#{author}: #{c.content}"
end.join("\n\n")
system_prompt = Comments::CompressCommand::SYSTEM_PROMPT.dup
if .present?
system_prompt += "\n\nAdditional instruction from the user: #{}"
end
agent = resolve_ai_agent(creative, topic_id)
unless agent
error_msg = I18n.t("collavre.comments.compress_command.no_agent")
creative..create!(user: user, topic_id: topic_id, content: "⚠️ #{error_msg}", skip_dispatch: true)
Rails.logger.error("[CompressJob] No AI agent found for creative #{creative_id}, topic #{topic_id}")
return
end
client = AiClient.new(
vendor: agent.llm_vendor,
model: agent.llm_model,
system_prompt: system_prompt,
llm_api_key: agent.llm_api_key || agent.creator&.llm_api_key,
gateway_url: agent.gateway_url.presence || agent.creator&.gateway_url,
context: {
creative: creative,
user: agent,
topic_id: topic_id
}
)
summary = String.new
result = client.chat([ { role: "user", text: conversation } ]) do |delta|
summary << delta
end
if result.nil? || summary.blank?
Rails.logger.error("[CompressJob] AI failed for topic #{topic_id}")
return
end
topic_name = topic.name.presence || "Topic"
title = I18n.t("collavre.comments.compress_command.summary_title", topic: topic_name)
summary_content = "**#{title}**\n\n#{summary}"
= .pluck(:id)
= creative..create!(
user: user,
topic_id: topic_id,
content: summary_content,
skip_dispatch: true )
= .last
last_is_command = &.content.to_s.strip.match?(compress_pattern)
= last_is_command ? [0..-2] : .to_a
CommentSnapshot.create!(
creative: creative,
topic_id: topic_id,
user: user,
operation: "compress",
comments_data: (),
result_comment:
)
creative..where(id: ).destroy_all
rescue ActiveRecord::RecordNotFound => e
Rails.logger.error("[CompressJob] Record not found: #{e.message}")
end
|