diff --git a/AIClasses/ToolDefinitions/AIToolDefinitions.ts b/AIClasses/ToolDefinitions/AIToolDefinitions.ts index 691b882..512569d 100644 --- a/AIClasses/ToolDefinitions/AIToolDefinitions.ts +++ b/AIClasses/ToolDefinitions/AIToolDefinitions.ts @@ -22,6 +22,7 @@ import { CreateVaultFolder } from "./Tools/CreateVaultFolder"; import { GetWebViewerContent } from "./Tools/GetWebViewerContent"; import { DeleteVaultFolder } from "./Tools/DeleteVaultFolder"; import { MoveVaultFolder } from "./Tools/MoveVaultFolder"; +import { ChatMode, chatModeAllowsEdits } from "Enums/ChatMode"; export abstract class AIToolDefinitions { @@ -31,10 +32,10 @@ export abstract class AIToolDefinitions { private static readonly definitionsList = [SearchVaultFiles, ReadVaultFiles, ListVaultFiles, GetWebViewerContent, WriteVaultFile, PatchVaultFile, DeleteVaultFiles, MoveVaultFiles, CreateVaultFolder, DeleteVaultFolder, MoveVaultFolder]; - public static agentDefinitions(destructive: boolean, planningMode: boolean, memories: boolean, updateMemories: boolean, webViewer: boolean): IAIToolDefinition[] { + public static agentDefinitions(chatMode: ChatMode, memories: boolean, updateMemories: boolean, webViewer: boolean): IAIToolDefinition[] { this.isGated = false; - if (planningMode) { + if (chatMode === ChatMode.Planning) { return [ExecuteWorkflow]; } @@ -56,7 +57,7 @@ export abstract class AIToolDefinitions { actions = actions.concat([UpdateMemories]); } - if (destructive) { + if (chatModeAllowsEdits(chatMode)) { actions = actions.concat([ WriteVaultFile, PatchVaultFile, @@ -110,7 +111,7 @@ export abstract class AIToolDefinitions { } public static executionAgentDefinitions(): IAIToolDefinition[] { - return [...this.agentDefinitions(true, false, false, false, false), CompleteTask]; + return [...this.agentDefinitions(ChatMode.Edit, false, false, false), CompleteTask]; } public static compactSummaryForPlanningAgent(): string { diff --git a/AIPrompts/SystemPrompt.ts b/AIPrompts/SystemPrompt.ts index 41a1ad3..79068ca 100644 --- a/AIPrompts/SystemPrompt.ts +++ b/AIPrompts/SystemPrompt.ts @@ -327,6 +327,19 @@ When searches return or reference images or PDFs: - Extract relevant information to answer the user's query - Reference the source file with [[wiki-links]] as usual +### User-Provided References + +The chat input supports an autocomplete reference system. When a user types \`@\`, \`/\`, or \`#\`, they can select matching vault items from a dropdown. Selected references are serialized into the message as: + +- \`file:"path/to/note.md"\` — a specific file the user selected with \`@\` +- \`folder:"path/to/folder"\` — a specific folder the user selected with \`/\` +- \`tag:"#tagname"\` — a specific tag the user selected with \`#\` + +**These references are always valid — the user selected them from live vault data.** You likely do not have to verify their existence. +Example: If the user says "create a note in \`folder:"Projects/2025"\`", the folder exists and should be used directly as the destination (does not need to be created first). + +--- + ### File Attachments **Users can attach files directly to their messages.** When a file is attached, its content is provided inline in the conversation. Attached files are likely NOT present in the vault so use the attached content directly. diff --git a/Components/ChatArea.svelte b/Components/ChatArea.svelte index 51a43dd..ad5a209 100644 --- a/Components/ChatArea.svelte +++ b/Components/ChatArea.svelte @@ -17,7 +17,6 @@ export let isSubmitting: boolean = false; export let chatContainer: HTMLDivElement; export let currentStreamingMessageId: string | null = null; - export let editModeActive: boolean = false; export function resetChatArea() { autoScroll = true; @@ -291,9 +290,9 @@ {/if} {/each} - + {#if isSubmitting} - + {/if}
diff --git a/Components/ChatInput.svelte b/Components/ChatInput.svelte index d8a84f2..e75a4b1 100644 --- a/Components/ChatInput.svelte +++ b/Components/ChatInput.svelte @@ -10,6 +10,7 @@ import type { Writable } from "svelte/store"; import type { InputService } from "Services/InputService"; import UserInstruction from "./UserInstruction.svelte"; + import ChatModeSelector from "./ChatModeSelector.svelte"; import DiffControls from "./DiffControls.svelte"; import type { EventService } from "Services/EventService"; import { Event } from "Enums/Event"; @@ -22,13 +23,13 @@ import { HelpModal } from "Modals/HelpModal"; import type { IPrompt } from "AIPrompts/IPrompt"; import type { SettingsService } from "Services/SettingsService"; + import { ChatMode, chatModeAllowsEdits, iconForChatMode } from "Enums/ChatMode"; export let attachments: Attachment[] = []; export let hasNoApiKey: boolean; export let isSubmitting: boolean; - export let editModeActive: boolean; - export let planningModeActive: boolean; + export let chatMode: ChatMode; export let onSubmit: (userRequest: string, formattedRequest: string) => void; export let onStop: () => void; @@ -47,9 +48,10 @@ let userInstructionButton: HTMLButtonElement; let webSearchButton: HTMLButtonElement; let submitButton: HTMLButtonElement; - let editModeButton: HTMLButtonElement; - let planningModeButton: HTMLButtonElement; + let attachmentButton: HTMLButtonElement; + let chatModeButton: HTMLButtonElement; + let chatModeSelectionAreaActive: boolean = false; let userInstructionAreaActive: boolean = false; let userInstructionActive: boolean = true; let stacked: boolean = false; @@ -198,12 +200,12 @@ } } - $: if (editModeButton) { - setIcon(editModeButton, editModeActive ? "pencil" : "pencil-off"); + $: if (attachmentButton) { + setIcon(attachmentButton, "paperclip"); } - $: if (planningModeButton) { - setIcon(planningModeButton, planningModeActive ? "list-ordered" : "list-x"); + $: if (chatModeButton) { + setIcon(chatModeButton, iconForChatMode(chatMode)); } $: inputPlaceholder = (() => { @@ -290,24 +292,8 @@ settingsService.saveSettings(); } - function toggleEditMode() { - if (planningModeActive) { - planningModeActive = false - } - editModeActive = !editModeActive; - focusInput(); - } - - function togglePlanningMode() { - if (planningModeActive) { - planningModeActive = false; - } else { - if (!editModeActive) { - toggleEditMode(); // Mandatory for planning mode - } - planningModeActive = true; - } - focusInput(); + function toggleChatModeSelectionArea() { + chatModeSelectionAreaActive = !chatModeSelectionAreaActive; } async function handleKeydown(e: KeyboardEvent) { @@ -501,9 +487,9 @@ } -
+
0 ? "var(--size-4-2)" : 0}> - +
0 ? "var(--size-4-2)" : 0}> @@ -522,9 +508,13 @@
+
+ +
+