diff --git a/web/src/message_summary.ts b/web/src/message_summary.ts index 6e55f03280..20d7fd9a49 100644 --- a/web/src/message_summary.ts +++ b/web/src/message_summary.ts @@ -8,6 +8,7 @@ import * as dialog_widget from "./dialog_widget.ts"; import {Filter} from "./filter.ts"; import {$t} from "./i18n.ts"; import * as message_fetch from "./message_fetch.ts"; +import * as rendered_markdown from "./rendered_markdown.ts"; import * as unread from "./unread.ts"; import * as unread_ops from "./unread_ops.ts"; import * as util from "./util.ts"; @@ -57,11 +58,13 @@ export function get_narrow_summary(channel_id: number, topic_name: string): void { success_continuation(response_data) { const data = z.object({summary: z.string()}).parse(response_data); - const message = data.summary; - $("#topic-summary-modal .modal__content").html( - render_topic_summary({ - message, - }), + const summary_markdown = data.summary; + const summary_html = render_topic_summary({ + summary_markdown, + }); + $("#topic-summary-modal .modal__content").html(summary_html); + rendered_markdown.update_elements( + $("#topic-summary-modal .modal__content"), ); }, }, diff --git a/web/templates/topic_summary.hbs b/web/templates/topic_summary.hbs index dcce06762c..dbbe2550a7 100644 --- a/web/templates/topic_summary.hbs +++ b/web/templates/topic_summary.hbs @@ -1 +1 @@ -

{{message}}

+

{{rendered_markdown summary_markdown}}

diff --git a/zerver/actions/message_summary.py b/zerver/actions/message_summary.py index bd122fda5b..91172da892 100644 --- a/zerver/actions/message_summary.py +++ b/zerver/actions/message_summary.py @@ -6,6 +6,7 @@ from django.conf import settings from django.utils.timezone import now as timezone_now from analytics.lib.counts import COUNT_STATS, do_increment_logging_stat +from zerver.lib.markdown import markdown_convert from zerver.lib.message import messages_for_ids from zerver.lib.narrow import ( LARGER_THAN_MAX_MESSAGE_ID, @@ -149,7 +150,7 @@ def do_summarize_narrow( f"Succinctly summarize this conversation based only on the information provided, " f"in up to {max_summary_length} sentences, for someone who is familiar with the context. " f"Mention key conclusions and actions, if any. Refer to specific people as appropriate. " - f"Don't use an intro phrase." + f"Don't use an intro phrase. You can use Zulip's CommonMark based formatting." ) messages = [ make_message(intro, "system"), @@ -204,4 +205,9 @@ def do_summarize_narrow( user_profile, COUNT_STATS["ai_credit_usage::day"], None, timezone_now(), credits_used ) - return response["choices"][0]["message"]["content"] + summary = response["choices"][0]["message"]["content"] + # TODO: This may want to fetch `MentionData`, in order to be able + # to process channel or user mentions that might be in the + # content. Requires a prompt that supports it. + rendered_summary = markdown_convert(summary, message_realm=user_profile.realm).rendered_content + return rendered_summary diff --git a/zerver/tests/fixtures/litellm/summary.json b/zerver/tests/fixtures/litellm/summary.json index 92ca6645f0..616a7af828 100644 --- a/zerver/tests/fixtures/litellm/summary.json +++ b/zerver/tests/fixtures/litellm/summary.json @@ -6,26 +6,26 @@ "role": "system" }, { - "content": "[{\"sender\":\"Iago\",\"content\":\"Zulip just launched a feature to generate summary of messages.\"},{\"sender\":\"Iago\",\"content\":\"Sounds awesome! This will greatly help me when catching up.\"}]", + "content": "[{\"sender\":\"Iago\",\"content\":\"Zulip just launched a feature to generate summary of messages.\"},{\"sender\":\"Iago\",\"content\":\"Sounds awesome! This will **greatly** help me when catching up.\"}]", "role": "user" }, { - "content": "Succinctly summarize this conversation based only on the information provided, in up to 4 sentences, for someone who is familiar with the context. Mention key conclusions and actions, if any. Refer to specific people as appropriate. Don't use an intro phrase.", + "content": "Succinctly summarize this conversation based only on the information provided, in up to 4 sentences, for someone who is familiar with the context. Mention key conclusions and actions, if any. Refer to specific people as appropriate. Don't use an intro phrase. You can use Zulip's CommonMark based formatting.", "role": "user" } ], "response": { - "id": "chatcmpl-aba152b1-546f-497b-9fcf-13410008e180", - "created": 1738095814, + "id": "chatcmpl-0ed48d2e-8956-444f-be81-f5d55392a280", + "created": 1738495155, "model": "groq/llama-3.3-70b-versatile", "object": "chat.completion", - "system_fingerprint": "fp_fcc3b74982", + "system_fingerprint": "fp_c0cfa69934", "choices": [ { "finish_reason": "stop", "index": 0, "message": { - "content": "Iago announced that Zulip has launched a feature to generate summaries of messages. Iago thinks this feature is awesome and believes it will greatly help when catching up. No actions are specified in the conversation. Iago appears to be looking forward to using the new feature.", + "content": "Iago announced that Zulip has launched a feature to generate summaries of messages. This feature will **greatly** help Iago when catching up. No actions were specified in the conversation. Iago seems to be looking forward to using this new feature.", "role": "assistant", "tool_calls": null, "function_call": null @@ -33,18 +33,18 @@ } ], "usage": { - "completion_tokens": 56, - "prompt_tokens": 163, - "total_tokens": 219, + "completion_tokens": 53, + "prompt_tokens": 178, + "total_tokens": 231, "completion_tokens_details": null, "prompt_tokens_details": null, - "queue_time": 0.43361592099999996, - "prompt_time": 0.02746035, - "completion_time": 0.203636364, - "total_time": 0.231096714 + "queue_time": 0.146625071, + "prompt_time": 0.041886488, + "completion_time": 0.261543978, + "total_time": 0.303430466 }, "x_groq": { - "id": "req_01jjq9ash2e56a6y3jd58cryx7" + "id": "req_01jk365q8afcht4th8crf3mhbg" } } } diff --git a/zerver/tests/test_message_summary.py b/zerver/tests/test_message_summary.py index cf62b66c62..ab1c68e7e9 100644 --- a/zerver/tests/test_message_summary.py +++ b/zerver/tests/test_message_summary.py @@ -39,7 +39,7 @@ class MessagesSummaryTestCase(ZulipTestCase): self.user, self.channel_name, content=content, topic_name=self.topic_name ) - content = "Sounds awesome! This will greatly help me when catching up." + content = "Sounds awesome! This will **greatly** help me when catching up." self.send_stream_message( self.user, self.channel_name, content=content, topic_name=self.topic_name )