Add CalDAV calendar integration, LLM-suggested tags, and settings refinements
- CalDAV integration: per-user calendar config, create/list/search events via caldav library, LLM tools for calendar operations from chat - LLM-suggested tags: new tag_suggestions service prompts LLM with existing tags and note content to suggest 3-5 relevant tags; exposed via API endpoints (suggest-tags, append-tag); integrated into editor views (suggest button + clickable pills) and chat tool calls (pills in ToolCallCard with one-click apply) - Settings/model UI refinements, generation task improvements Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,6 @@ import { useSettingsStore } from "@/stores/settings";
|
||||
import { apiGet } from "@/api/client";
|
||||
import { renderMarkdown } from "@/utils/markdown";
|
||||
import ChatMessage from "@/components/ChatMessage.vue";
|
||||
import ModelSelector from "@/components/ModelSelector.vue";
|
||||
import ToolCallCard from "@/components/ToolCallCard.vue";
|
||||
import type { Note } from "@/types/note";
|
||||
|
||||
@@ -30,9 +29,6 @@ const noteSearchResults = ref<{ id: number; title: string }[]>([]);
|
||||
const noteSearchLoading = ref(false);
|
||||
let noteSearchTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
// Model selection
|
||||
const selectedModel = ref("");
|
||||
|
||||
// Exclude tracking (session-scoped per conversation)
|
||||
const excludedNoteIds = ref<Set<number>>(new Set());
|
||||
|
||||
@@ -76,12 +72,6 @@ onMounted(async () => {
|
||||
await store.fetchConversations();
|
||||
if (convId.value) {
|
||||
await store.fetchConversation(convId.value);
|
||||
if (store.currentConversation?.model) {
|
||||
selectedModel.value = store.currentConversation.model;
|
||||
}
|
||||
}
|
||||
if (!selectedModel.value) {
|
||||
selectedModel.value = store.defaultModel;
|
||||
}
|
||||
nextTick(() => inputEl.value?.focus());
|
||||
});
|
||||
@@ -112,26 +102,6 @@ watch(convId, async (newId) => {
|
||||
nextTick(() => inputEl.value?.focus());
|
||||
});
|
||||
|
||||
// Sync selectedModel from loaded conversation
|
||||
watch(
|
||||
() => store.currentConversation?.model,
|
||||
(model) => {
|
||||
if (model) selectedModel.value = model;
|
||||
}
|
||||
);
|
||||
|
||||
// Persist model changes to backend
|
||||
watch(selectedModel, (newModel, oldModel) => {
|
||||
if (
|
||||
newModel &&
|
||||
oldModel &&
|
||||
newModel !== oldModel &&
|
||||
store.currentConversation
|
||||
) {
|
||||
store.updateConversationModel(store.currentConversation.id, newModel);
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => store.streamingContent,
|
||||
() => scrollToBottom()
|
||||
@@ -155,7 +125,7 @@ async function selectConversation(id: number) {
|
||||
}
|
||||
|
||||
async function newConversation() {
|
||||
const conv = await store.createConversation("", selectedModel.value);
|
||||
const conv = await store.createConversation();
|
||||
await store.fetchConversation(conv.id);
|
||||
router.push(`/chat/${conv.id}`);
|
||||
}
|
||||
@@ -344,10 +314,6 @@ function excludeAutoNote(noteId: number) {
|
||||
<line x1="3" y1="18" x2="21" y2="18"/>
|
||||
</svg>
|
||||
</button>
|
||||
<ModelSelector
|
||||
v-model="selectedModel"
|
||||
:disabled="store.streaming"
|
||||
/>
|
||||
<h2>{{ store.currentConversation.title || "New Chat" }}</h2>
|
||||
<button
|
||||
v-if="store.currentConversation.messages.length"
|
||||
|
||||
Reference in New Issue
Block a user