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

Commit 22aa932

Browse files
committed
Merge branch 'main' into dev/glimmer-post-stream
2 parents c816517 + 09a6841 commit 22aa932

File tree

90 files changed

+1550
-306
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+1550
-306
lines changed

app/controllers/discourse_ai/ai_bot/conversations_controller.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ def index
1010
page = params[:page].to_i
1111
per_page = params[:per_page]&.to_i || 40
1212

13-
bot_user_ids = EntryPoint.all_bot_ids
1413
base_query =
1514
Topic
1615
.private_messages_for_user(current_user)
@@ -26,7 +25,7 @@ def index
2625
pms = base_query.order(last_posted_at: :desc).offset(page * per_page).limit(per_page)
2726

2827
render json: {
29-
conversations: serialize_data(pms, BasicTopicSerializer),
28+
conversations: serialize_data(pms, ListableTopicSerializer),
3029
meta: {
3130
total: total,
3231
page: page,

assets/javascripts/discourse/components/ai-bot-header-icon.gjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { AI_CONVERSATIONS_PANEL } from "../services/ai-conversations-sidebar-man
1010
export default class AiBotHeaderIcon extends Component {
1111
@service composer;
1212
@service currentUser;
13+
@service navigationMenu;
1314
@service router;
1415
@service sidebarState;
1516
@service siteSettings;
@@ -35,6 +36,7 @@ export default class AiBotHeaderIcon extends Component {
3536

3637
get clickShouldRouteOutOfConversations() {
3738
return (
39+
!this.navigationMenu.isHeaderDropdownMode &&
3840
this.siteSettings.ai_enable_experimental_bot_ux &&
3941
this.sidebarState.currentPanel?.key === AI_CONVERSATIONS_PANEL
4042
);

assets/javascripts/discourse/controllers/discourse-ai-bot-conversations.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,15 @@ export default class DiscourseAiBotConversations extends Controller {
4848
_autoExpandTextarea() {
4949
this.textarea.style.height = "auto";
5050
this.textarea.style.height = this.textarea.scrollHeight + "px";
51+
52+
// Get the max-height value from CSS (30vh)
53+
const maxHeight = parseInt(getComputedStyle(this.textarea).maxHeight, 10);
54+
55+
// Only enable scrolling if content exceeds max-height
56+
if (this.textarea.scrollHeight > maxHeight) {
57+
this.textarea.style.overflowY = "auto";
58+
} else {
59+
this.textarea.style.overflowY = "hidden";
60+
}
5161
}
5262
}

assets/javascripts/initializers/ai-conversations-sidebar.js

Lines changed: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { tracked } from "@glimmer/tracking";
2+
import { htmlSafe } from "@ember/template";
23
import { TrackedArray } from "@ember-compat/tracked-built-ins";
34
import { ajax } from "discourse/lib/ajax";
45
import { bind } from "discourse/lib/decorators";
6+
import { autoUpdatingRelativeAge } from "discourse/lib/formatter";
57
import { withPluginApi } from "discourse/lib/plugin-api";
68
import { i18n } from "discourse-i18n";
79
import AiBotSidebarNewConversation from "../discourse/components/ai-bot-sidebar-new-conversation";
@@ -27,13 +29,14 @@ export default {
2729
);
2830
const appEvents = api.container.lookup("service:app-events");
2931
const messageBus = api.container.lookup("service:message-bus");
32+
const navigationMenu = api.container.lookup("service:navigationMenu");
3033

3134
api.addSidebarPanel(
3235
(BaseCustomSidebarPanel) =>
3336
class AiConversationsSidebarPanel extends BaseCustomSidebarPanel {
3437
key = AI_CONVERSATIONS_PANEL;
3538
hidden = true;
36-
displayHeader = true;
39+
displayHeader = !navigationMenu.isHeaderDropdownMode;
3740
expandActiveSection = true;
3841
}
3942
);
@@ -85,6 +88,10 @@ export default {
8588
@tracked links = new TrackedArray();
8689
@tracked topics = [];
8790
@tracked hasMore = [];
91+
@tracked loadedTodayLabel = false;
92+
@tracked loadedSevenDayLabel = false;
93+
@tracked loadedThirtyDayLabel = false;
94+
@tracked loadedMonthLabels = new Set();
8895
page = 0;
8996
isFetching = false;
9097
totalTopicsCount = 0;
@@ -127,7 +134,15 @@ export default {
127134
}
128135

129136
addNewPMToSidebar(topic) {
130-
this.links = [new AiConversationLink(topic), ...this.links];
137+
// Reset category labels since we're adding a new topic
138+
this.loadedTodayLabel = false;
139+
this.loadedSevenDayLabel = false;
140+
this.loadedThirtyDayLabel = false;
141+
this.loadedMonthLabels.clear();
142+
143+
this.topics = [topic, ...this.topics];
144+
this.buildSidebarLinks();
145+
131146
this.watchForTitleUpdate(topic);
132147
}
133148

@@ -206,10 +221,82 @@ export default {
206221
this.fetchMessages(true);
207222
}
208223

209-
buildSidebarLinks() {
210-
this.links = this.topics.map(
211-
(topic) => new AiConversationLink(topic)
224+
groupByDate(topic) {
225+
const now = new Date();
226+
const lastPostedAt = new Date(topic.last_posted_at);
227+
const daysDiff = Math.round(
228+
(now - lastPostedAt) / (1000 * 60 * 60 * 24)
212229
);
230+
231+
if (daysDiff <= 1 || !topic.last_posted_at) {
232+
if (!this.loadedTodayLabel) {
233+
this.loadedTodayLabel = true;
234+
return {
235+
text: i18n("discourse_ai.ai_bot.conversations.today"),
236+
classNames: "date-heading",
237+
name: "date-heading-today",
238+
};
239+
}
240+
}
241+
// Last 7 days group
242+
else if (daysDiff <= 7) {
243+
if (!this.loadedSevenDayLabel) {
244+
this.loadedSevenDayLabel = true;
245+
return {
246+
text: i18n("discourse_ai.ai_bot.conversations.last_7_days"),
247+
classNames: "date-heading",
248+
name: "date-heading-last-7-days",
249+
};
250+
}
251+
}
252+
// Last 30 days group
253+
else if (daysDiff <= 30) {
254+
if (!this.loadedThirtyDayLabel) {
255+
this.loadedThirtyDayLabel = true;
256+
return {
257+
text: i18n(
258+
"discourse_ai.ai_bot.conversations.last_30_days"
259+
),
260+
classNames: "date-heading",
261+
name: "date-heading-last-30-days",
262+
};
263+
}
264+
}
265+
// Group by month for older conversations
266+
else {
267+
const month = lastPostedAt.getMonth();
268+
const year = lastPostedAt.getFullYear();
269+
const monthKey = `${year}-${month}`;
270+
271+
if (!this.loadedMonthLabels.has(monthKey)) {
272+
this.loadedMonthLabels.add(monthKey);
273+
274+
const formattedDate = autoUpdatingRelativeAge(
275+
new Date(topic.last_posted_at)
276+
);
277+
278+
return {
279+
text: htmlSafe(formattedDate),
280+
classNames: "date-heading",
281+
name: `date-heading-${monthKey}`,
282+
};
283+
}
284+
}
285+
}
286+
287+
buildSidebarLinks() {
288+
// Reset date header tracking
289+
this.loadedTodayLabel = false;
290+
this.loadedSevenDayLabel = false;
291+
this.loadedThirtyDayLabel = false;
292+
this.loadedMonthLabels.clear();
293+
294+
this.links = [...this.topics].flatMap((topic) => {
295+
const dateLabel = this.groupByDate(topic);
296+
return dateLabel
297+
? [dateLabel, new AiConversationLink(topic)]
298+
: [new AiConversationLink(topic)];
299+
});
213300
}
214301

215302
watchForTitleUpdate(topic) {

assets/stylesheets/modules/ai-bot-conversations/common.scss

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ body.has-ai-conversations-sidebar {
1010
margin: 1.8em 1rem 0;
1111
}
1212

13+
.sidebar-toggle-all-sections {
14+
display: none;
15+
}
16+
1317
.sidebar-wrapper {
1418
.ai-conversations-panel {
1519
padding-top: 1em;
@@ -18,19 +22,20 @@ body.has-ai-conversations-sidebar {
1822
// ai related sidebar content
1923
[data-section-name="ai-conversations-history"] {
2024
.sidebar-section-header-wrapper {
21-
pointer-events: none;
22-
font-size: var(--font-down-1);
23-
24-
.sidebar-section-header-caret {
25-
display: none;
26-
}
27-
28-
.sidebar-section-header-text {
29-
letter-spacing: 0.5px;
30-
}
25+
display: none;
3126
}
3227

3328
.sidebar-section-link-wrapper {
29+
.sidebar-section-link.date-heading {
30+
pointer-events: none;
31+
cursor: default;
32+
color: var(--primary-medium);
33+
opacity: 0.8;
34+
font-weight: 700;
35+
margin-top: 1em;
36+
font-size: var(--font-down-2);
37+
}
38+
3439
.sidebar-section-link {
3540
height: unset;
3641
padding-block: 0.65em;
@@ -228,19 +233,13 @@ body.has-ai-conversations-sidebar {
228233
max-height: 2.5em;
229234
}
230235

231-
.spinner {
232-
margin: 0;
233-
width: 2em;
234-
height: 2em;
235-
}
236-
237236
#ai-bot-conversations-input {
238237
width: 100%;
239238
margin: 0;
240239
resize: none;
241240
border-radius: var(--d-button-border-radius);
242241
max-height: 30vh;
243-
overflow: hidden;
242+
overflow-y: hidden;
244243

245244
&:focus {
246245
outline: none;

assets/stylesheets/modules/ai-helper/common/ai-helper.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@
277277
}
278278

279279
#reply-control {
280+
.composer-actions.is-expanded,
280281
.composer-popup {
281282
// need to raise the z-index here
282283
// because we need another layer to put the AI icon above dropdowns

config/locales/client.ar.yml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,14 @@ ar:
138138
label: "درجة الحرارة"
139139
discourse_ai:
140140
title: "الذكاء الاصطناعي"
141+
features:
142+
back: "الرجوع"
143+
list:
144+
header:
145+
name: "الاسم"
146+
groups: "المجموعات"
147+
edit: "تعديل"
148+
set_up: "إعداد"
141149
modals:
142150
select_option: "حدِّد خيارًا..."
143151
spam:
@@ -338,7 +346,6 @@ ar:
338346
name: "معرِّف النموذج"
339347
provider: "مقدِّم الخدمة"
340348
tokenizer: "أداة الترميز"
341-
max_prompt_tokens: "عدد الرموز المميزة لرسالة المطالبة"
342349
url: "عنوان URL لخدمة استضافة النموذج"
343350
api_key: "مفتاح API لخدمة استضافة النموذج"
344351
enabled_chat_bot: "السماح بمحدِّد روبوت الذكاء الاصطناعي"
@@ -388,12 +395,8 @@ ar:
388395
anthropic-claude-3-7-sonnet: "النموذج الأكثر ذكاءً لدى Anthropic"
389396
anthropic-claude-3-5-haiku: "سريع وفعَّال من حيث التكلفة"
390397
anthropic-claude-3-opus: "يبرع في الكتابة والمهام المعقدة"
391-
google-gemini-1-5-pro: "نموذج متعدد متوسط الحجم قادر على تنفيذ مجموعة واسعة من المهام"
392-
google-gemini-1-5-flash: "خفيف وسريع وفعَّال من حيث التكلفة مع الاستدلال متعدد النماذج"
393-
open_ai-gpt-4-turbo: "نموذج عالي الذكاء من الجيل السابق"
394-
open_ai-gpt-4o: "نموذج عالي الذكاء للمهام المعقدة والمتعددة الخطوات"
395-
open_ai-gpt-4o-mini: "نموذج صغير سريع وبأسعارٍ معقولة للمهام الخفيفة"
396-
open_ai-o1-mini: "نموذج استدلال فعَّال من حيث التكلفة"
398+
google-gemini-2-5-pro: "نموذج متعدد متوسط الحجم قادر على تنفيذ مجموعة واسعة من المهام"
399+
google-gemini-2-0-flash: "خفيف وسريع وفعَّال من حيث التكلفة مع الاستدلال متعدد النماذج"
397400
samba_nova-Meta-Llama-3-1-8B-Instruct: "نموذج متعدد اللغات خفيف وفعَّال"
398401
samba_nova-Meta-Llama-3-3-70B-Instruct": "نموذج قوي متعدد الأغراض"
399402
mistral-mistral-large-latest: "النموذج الأقوى لدى Mistral"
@@ -416,7 +419,6 @@ ar:
416419
success: "تم بنجاح!"
417420
failure: "أرجعت محاولة التواصل مع النموذج هذا الخطأ: %{error}"
418421
hints:
419-
max_prompt_tokens: "الحد الأقصى لعدد الرموز المميزة لرسالة المطالبة. كقاعدة عامة، يجب أن يمثل هذا 50% من نافذة سياق النموذج."
420422
name: "إننا نقوم بتضمين هذا في استدعاء واجهة برمجة التطبيقات (API) لتحديد النموذج الذي سنستخدمه"
421423
vision_enabled: "إذا تم تفعيله، فسيحاول الذكاء الاصطناعي فهم الصور. إنه يعتمد على النموذج المُستخدَم لدعم الرؤية. هذه الميزة مدعومة بأحدث النماذج من Anthropic وGoogle وOpenAI."
422424
enabled_chat_bot: "إذا تم تفعيله، يمكن للمستخدمين تحديد هذا النموذج عند إنشاء الرسائل الخاصة باستخدام روبوت الذكاء الاصطناعي"

config/locales/client.be.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ be:
3434
canned_reply:
3535
label: "Адказаць"
3636
discourse_ai:
37+
features:
38+
back: "Назад"
39+
list:
40+
header:
41+
name: "Імя"
42+
groups: "групы"
43+
edit: "Рэдагаваць"
3744
spam:
3845
short_title: "Спам"
3946
enable: "Уключыць"

config/locales/client.bg.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ bg:
3434
canned_reply:
3535
label: "Отговорете"
3636
discourse_ai:
37+
features:
38+
back: "Назад"
39+
list:
40+
header:
41+
name: "Име "
42+
groups: "Групи"
43+
edit: "Редактирай"
3744
modals:
3845
select_option: "Изберете опция..."
3946
spam:

config/locales/client.bs_BA.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ bs_BA:
3434
canned_reply:
3535
label: "Odgovori"
3636
discourse_ai:
37+
features:
38+
back: "Prethodno"
39+
list:
40+
header:
41+
name: "Ime"
42+
groups: "Groups"
43+
edit: "Edit"
3744
modals:
3845
select_option: "Odaberi opciju..."
3946
spam:

0 commit comments

Comments
 (0)