Add note context visibility in chat and standardize UI design tokens

Improve chat context: build_context() now returns metadata about auto-found
notes, emitted as an SSE event so the frontend can display context pills
showing which notes influenced the response. Users can promote notes for
deeper context (+) or exclude irrelevant ones (x). A note picker lets users
manually attach notes. Multi-word search uses per-term AND matching, and
auto-search iterates keywords individually for broader OR-style coverage.

Standardize styling: introduce CSS design tokens (--radius-sm/md/lg/pill,
--color-success/warning/overlay, --focus-ring) and migrate all components
to use them. Fix header alignment to full-width, add active nav link state,
replace hardcoded colors with CSS variables, and normalize button padding.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 06:49:12 -05:00
parent 39bcd7a8fa
commit fb18d2c41d
26 changed files with 1070 additions and 237 deletions
+17 -2
View File
@@ -10,6 +10,7 @@ import {
import type {
Conversation,
ConversationDetail,
ContextMeta,
Message,
OllamaModel,
OllamaStatus,
@@ -22,6 +23,7 @@ export const useChatStore = defineStore("chat", () => {
const loading = ref(false);
const streaming = ref(false);
const streamingContent = ref("");
const lastContextMeta = ref<ContextMeta | null>(null);
const models = ref<OllamaModel[]>([]);
const ollamaStatus = ref<"checking" | "available" | "unavailable">("checking");
const modelStatus = ref<"checking" | "ready" | "not_found">("checking");
@@ -90,10 +92,15 @@ export const useChatStore = defineStore("chat", () => {
}
}
async function sendMessage(content: string, contextNoteId?: number | null) {
async function sendMessage(
content: string,
contextNoteId?: number | null,
excludeNoteIds?: number[],
) {
if (!currentConversation.value) return;
const convId = currentConversation.value.id;
lastContextMeta.value = null;
// Add optimistic user message
const userMsg: Message = {
@@ -112,8 +119,15 @@ export const useChatStore = defineStore("chat", () => {
try {
await apiStreamPost(
`/api/chat/conversations/${convId}/messages`,
{ content, context_note_id: contextNoteId },
{
content,
context_note_id: contextNoteId,
exclude_note_ids: excludeNoteIds?.length ? excludeNoteIds : undefined,
},
(data) => {
if (data.context) {
lastContextMeta.value = data.context as ContextMeta;
}
if (data.chunk) {
streamingContent.value += data.chunk as string;
}
@@ -207,6 +221,7 @@ export const useChatStore = defineStore("chat", () => {
loading,
streaming,
streamingContent,
lastContextMeta,
models,
ollamaStatus,
modelStatus,