-
+ >
+
+
+ New Briefing Update
+
+
+
@@ -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;
diff --git a/frontend/src/types/chat.ts b/frontend/src/types/chat.ts
index 9d97812..162dd99 100644
--- a/frontend/src/types/chat.ts
+++ b/frontend/src/types/chat.ts
@@ -28,6 +28,7 @@ export interface Message {
context_note_id: number | null;
context_note_title?: string | null;
tool_calls?: ToolCallRecord[] | null;
+ metadata?: Record
| null;
created_at: string;
timing?: GenerationTiming;
thinking?: string;
diff --git a/src/fabledassistant/services/llm.py b/src/fabledassistant/services/llm.py
index 67abd71..178e501 100644
--- a/src/fabledassistant/services/llm.py
+++ b/src/fabledassistant/services/llm.py
@@ -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: