fix(briefing): use briefing context for follow-ups; add slot separator
- build_context: when conversation_type is 'briefing', inject a system prompt instruction telling the model to answer from conversation history and article context instead of searching the web - Consolidate briefing conversation type detection to one DB query (was being checked twice — once for the system prompt addition, once for article context injection) - ChatPanel: render a visual 'New Briefing Update' separator line before 2nd+ briefing slot messages (identified by metadata.rss_item_ids) - types/chat.ts: add metadata field to Message interface Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -299,12 +299,22 @@ defineExpose({ focus, prefill, send })
|
||||
<!-- Message list -->
|
||||
<div ref="messagesEl" class="messages-container">
|
||||
<div class="messages-inner">
|
||||
<ChatMessage
|
||||
v-for="msg in store.currentConversation?.messages ?? []"
|
||||
<template
|
||||
v-for="(msg, index) in store.currentConversation?.messages ?? []"
|
||||
:key="msg.id"
|
||||
:message="msg"
|
||||
@save-as-note="handleSaveAsNote"
|
||||
/>
|
||||
>
|
||||
<!-- Briefing slot separator: shown before a 2nd+ briefing slot message -->
|
||||
<div
|
||||
v-if="briefingMode && index > 0 && msg.role === 'assistant' && msg.metadata?.rss_item_ids"
|
||||
class="briefing-slot-separator"
|
||||
>
|
||||
<span>New Briefing Update</span>
|
||||
</div>
|
||||
<ChatMessage
|
||||
:message="msg"
|
||||
@save-as-note="handleSaveAsNote"
|
||||
/>
|
||||
</template>
|
||||
<!-- Streaming bubble -->
|
||||
<ChatStreamingBubble v-if="store.streaming" />
|
||||
<!-- Queued messages -->
|
||||
@@ -523,6 +533,28 @@ defineExpose({ focus, prefill, send })
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* Briefing slot separator */
|
||||
.briefing-slot-separator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin: 1.25rem 0 0.5rem;
|
||||
color: var(--color-text-muted, #888);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
opacity: 0.7;
|
||||
}
|
||||
.briefing-slot-separator::before,
|
||||
.briefing-slot-separator::after {
|
||||
content: '';
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: var(--color-border, #333);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Context sidebar */
|
||||
.context-sidebar {
|
||||
width: 200px;
|
||||
|
||||
@@ -28,6 +28,7 @@ export interface Message {
|
||||
context_note_id: number | null;
|
||||
context_note_title?: string | null;
|
||||
tool_calls?: ToolCallRecord[] | null;
|
||||
metadata?: Record<string, unknown> | null;
|
||||
created_at: string;
|
||||
timing?: GenerationTiming;
|
||||
thinking?: string;
|
||||
|
||||
@@ -607,6 +607,25 @@ async def build_context(
|
||||
f"\n\n--- Earlier Conversation ---\n{history_summary}\n--- End Earlier Conversation ---"
|
||||
)
|
||||
|
||||
# Detect briefing conversation — used for both system prompt instruction and article injection
|
||||
_is_briefing_conv = False
|
||||
if conv_id is not None:
|
||||
from fabledassistant.models import async_session as _async_session
|
||||
from fabledassistant.models.conversation import Conversation as _Conversation
|
||||
async with _async_session() as _sess:
|
||||
_conv = await _sess.get(_Conversation, conv_id)
|
||||
if _conv and getattr(_conv, "conversation_type", None) == "briefing":
|
||||
_is_briefing_conv = True
|
||||
|
||||
if _is_briefing_conv:
|
||||
system_content += (
|
||||
"\n\nYou are in a briefing conversation. "
|
||||
"The conversation history contains today's briefing — news stories, weather, and tasks. "
|
||||
"When the user asks about a topic, person, or event from the briefing, answer directly "
|
||||
"from the conversation history and the article context that follows. "
|
||||
"Do NOT search the web for information that is already present in the briefing."
|
||||
)
|
||||
|
||||
context_meta: dict = {
|
||||
"context_note_id": None,
|
||||
"context_note_title": None,
|
||||
@@ -769,16 +788,10 @@ async def build_context(
|
||||
)
|
||||
|
||||
# Briefing article context for follow-up Q&A
|
||||
if conv_id is not None:
|
||||
from fabledassistant.models import async_session as _async_session
|
||||
from fabledassistant.models.conversation import Conversation
|
||||
|
||||
async with _async_session() as _sess:
|
||||
_conv = await _sess.get(Conversation, conv_id)
|
||||
if _conv and getattr(_conv, "conversation_type", None) == "briefing":
|
||||
article_context = await _build_briefing_article_context(conv_id)
|
||||
if article_context:
|
||||
user_context_parts.append(article_context.strip())
|
||||
if _is_briefing_conv:
|
||||
article_context = await _build_briefing_article_context(conv_id) # type: ignore[arg-type]
|
||||
if article_context:
|
||||
user_context_parts.append(article_context.strip())
|
||||
|
||||
# Build final user message — context prefix (if any) followed by the actual message
|
||||
if user_context_parts:
|
||||
|
||||
Reference in New Issue
Block a user