diff --git a/src/docs/Reference-Spec.md b/src/docs/Reference-Spec.md index e69de29..a24a319 100644 --- a/src/docs/Reference-Spec.md +++ b/src/docs/Reference-Spec.md @@ -0,0 +1,127 @@ +# Техническое Задание: Система Ссылок и Раскрытия Контента в LLM Agent Plugin Obsidian + +## 1. Введение + +Данный документ описывает функциональность системы ссылок и механизм раскрытия контента в плагине LLM Agent для Obsidian. Целью является предоставление пользователю возможности динамически включать содержимое файлов (заметок, документов, кода) и шаблонов (специальных промптов) в свои запросы к LLM-агенту, используя удобный синтаксис ссылок, автодополнение и визуальное представление. + +Система вдохновлена подходом таких инструментов, как Continue.dev, но адаптирована под экосистему Obsidian и требования пользователя. + +## 2. Терминология + +* **Ссылка:** Специальный синтаксис в сообщении пользователя, указывающий на файл или промпт в хранилище Obsidian. +* **Одинарная ссылка:** Ссылка, содержимое которой раскрывается только один раз, при отправке текущего сообщения на сервер. В последующих сообщениях эта ссылка остаётся в своём исходном виде. Имеет префикс `@` (для файлов) или `#` (для промптов). +* **Постоянная ссылка (Persistent Reference):** Ссылка, содержимое которой раскрывается при отправке *любого* сообщения пользователя, если она присутствовала в предыдущих сообщениях. Предназначена для поддержания постоянного контекста. Имеет префикс `@@` (для файлов) или `##` (для промптов). +* **Промпт:** Markdown-файл, содержащий шаблон запроса или часть запроса для LLM. Хранится в специально выделенной папке. +* **Шаблонная ссылка (Template Reference):** Ссылка внутри *промпта* на другой промпт. Использует синтаксис `@{prompt_name}`. Поддерживает только один уровень вложенности (нет рекурсии). +* **Бокс ссылки (Reference Box):** Визуальное представление ссылки в поле ввода (contenteditable div) после её выбора пользователем через автодополнение. Содержит иконку и имя. +* **Раскрытие контента (Content Expansion):** Процесс замены ссылки её фактическим содержимым файла или промпта перед отправкой запроса LLM-агенту. +* **Снапшот (Snapshot):** Сохранённое содержимое файла на момент его раскрытия. (**TODO**: будет реализовано позднее в отдельной таблице БД.) + +## 3. Требования к Функциональности + +### 3.1. Синтаксис Ссылок в Поле Ввода + +Система должна распознавать следующие типы ссылок: + +* **Ссылки на файлы:** + * `@<имя_файла>`: Одинарная ссылка на файл. + * `@@<имя_файла>`: Постоянная ссылка на файл. +* **Ссылки на промпты:** + * `#<имя_промпта>`: Одинарная ссылка на промпт. + * `##<имя_промпта>`: Постоянная ссылка на промпт. + +**Правила именования:** +* `<имя_файла>` и `<имя_промпта>` должны соответствовать `basename` файла (название файла без расширения и пути). +* Ссылки могут содержать пробелы, если имя файла/промпта заключено в кавычки, например, `@ "My Awesome File"`. В противном случае пробелы являются разделителями. + +### 3.2. Автодополнение Ссылок (Autocomplete) + +При вводе пользователем символов `@`, `@@`, `#`, `##` в поле ввода сообщения (ChatPanel), система должна показывать выпадающий список (autocomplete) релевантных файлов или промптов. + +* **Триггеры:** Ввод `@` или `#`. Автодополнение должно появляться, как только пользователь начинает вводить имя после префикса. +* **Фильтрация:** Список должен фильтроваться по мере ввода имени файла/промпта. +* **Опции:** Каждая опция в списке автодополнения должна включать: + * Иконку (соответствующую типу файла или промпту). + * Имя файла/промпта. + * Путь к файлу (относительно корня хранилища Obsidian, может быть сокращён). +* **Навигация:** Пользователь должен иметь возможность навигировать по списку с помощью клавиш `ArrowUp`/`ArrowDown`. +* **Выбор:** Выбор элемента осуществляется по `Enter` или `Tab` (или кликом). +* **Позиционирование:** Выпадающий список должен позиционироваться динамически: + * Если есть место, он появляется под курсором. + * Если места снизу недостаточно, он появляется над курсором. + * Должен учитывать границы экрана. + +### 3.3. Визуальное Представление Ссылок (Reference Boxes) + +После выбора элемента из списка автодополнения, текстовое представление ссылки в поле ввода должно заменяться на визуальный "бокс ссылки". + +* **Состав бокса:** Иконка ( Obsidian icon, соответствующая типу) и имя файла/промпта. +* **Стилизация:** + * Боксы для файлов (`@`/`@@`) и промптов (`#`/`##`) должны иметь отличающиеся цветовые схемы (фон, рамка). + * Боксы для одинарных ссылок (`@`/`#`) и постоянных ссылок (`@@`/`##`) должны иметь отличающиеся стили (например, более яркий фон/толстая рамка для постоянных). +* **Интерактивность:** При клике на бокс, должна быть предусмотрена возможность предпросмотра содержимого файла/промпта (функциональность **TODO** для будущих итераций). +* **Редактирование:** Пользователь должен иметь возможность удалять или редактировать боксы (например, нажать Delete/Backspace). +* **Сохранение информации:** Бокс должен содержать данные, достаточные для восстановления исходной ссылки (тип, имя, путь, признак постоянной ссылки). + +### 3.4. Раскрытие Контента перед Отправкой на Сервер + +Перед отправкой сообщения пользователя на backend LLM-агента, все ссылки в сообщении должны быть раскрыты. + +* **Одинарные ссылки (`@`/`#`):** Содержимое файла/промпта раскрывается и вставляется *только* в текущее отправляемое сообщение. В истории чата (в поле ввода) ссылка остаётся как бокс или текстовое представление. +* **Постоянные ссылки (`@@`/`##`):** Содержимое файла/промпта раскрывается и вставляется в текущее отправляемое сообщение. Более того, при загрузке истории для любого узла, если в этой истории есть сообщения пользователя с *постоянными* ссылками, их содержимое также должно быть раскрыто. Это обеспечивает поддержание постоянного контекста для LLM. +* **Форматирование раскрытого контента:** Раскрытое содержимое должно быть обернуто специальными маркерами для ясности, например: + ``` + --- Содержимое файла: my-file.md --- + (текст файла) + --- Конец файла: my-file.md --- + ``` +* **Размер файла:** Нет явных ограничений на размер файла для раскрытия. В случае превышения разумного размера, пользователь и/или LLM-агент могут обрабатывать это (например, через суммаризацию, но это вне рамок данной задачи). +* **Обработка ошибок:** Если файл/промпт не найден, вместо содержимого вставляется сообщение об ошибке (например, `[Ошибка: Файл "filename" не найден]`). +* **TODO: Снапшоты:** В будущем будет реализована функция сохранения "снимка" содержимого файла на момент его раскрытия. Это позволит гарантировать воспроизводимость диалога, даже если исходный файл изменится. + +### 3.5. Система Промптов и Шаблонные Ссылки + +* **Папка для промптов:** Пользователь должен указать путь к папке в настройках плагина, где хранятся все промпты. Все промпты являются Markdown-файлами (`.md`). +* **Шаблонные ссылки ВНУТРИ промптов (`@{prompt_name}`):** + * Промпты могут содержать ссылки на другие промпты. Синтаксис: `@{prompt_name}`. + * **Ограничение:** Поддерживается только один уровень вложенности. То есть, промпт C не может ссылаться на промпт B, который в свою очередь ссылается на промпт A. (A -> B -> C -> LLM is OK, but A -> B -> C -> B -> LLM is not). + * **Пример:** `prompts/base-personality.md` может содержать текст, а `prompts/game-master.md` может начинаться с `@{base-personality}`. +* **Наследование типа подстановки:** Если промпт `master-prompt` ссылается на `sub-prompt` через `@{sub-prompt}`, и `master-prompt` был вызван как `##master-prompt` (постоянная ссылка), то содержимое `sub-prompt` также должно раскрыться как часть постоянного контекста. То есть, тип (одинарный/постоянный) определяется префиксом (`#`/`##`) корневой ссылки пользователем в ChatPanel. +* **Валидация промптов:** При сохранении промпта (или при попытке его раскрытия), система должна проверять корректность синтаксиса `@{...}` и наличие файлов, на которые ссылаются шаблонные ссылки. Ошибки должны быть зарегистрированы. + +### 3.6. Настройки Плагина + +В настройках плагина должны быть добавлены следующие опции: + +* **`promptsFolder`**: (Строка) Путь к папке, где хранятся Markdown-файлы промптов. По умолчанию: "prompts". +* **`enableFileReferences`**: (Boolean) Включить/выключить функцию ссылок на файлы (@/@@). По умолчанию: `true`. +* **`enablePromptReferences`**: (Boolean) Включить/выключить функцию ссылок на промпты (#/##). По умолчанию: `true`. + +### 3.7. Интеграция с Backend + +* Frontend должен отправлять на backend *полностью раскрытый* текст сообщения. +* Backend не должен знать о системе ссылок, он работает только с конечным текстом. +* **TODO: Снапшоты (Backend):** Позднее, при реализации снапшотов, в модель данных `AgentState` и в базу данных (`graph_history_manager`) будут добавлены поля для хранения информации о раскрытых файлах и их содержимом. + +### 3.8. Технические Требования + +* **Производительность:** Автодополнение и раскрытие контента должны работать быстро, не вызывая заметных задержек в UI. +* **Совместимость:** Должна быть сохранена совместимость с существующей функциональностью плагина (слеш-команды, граф диалогов). +* **Иконки:** Использовать стандартные иконки Obsidian. +* **CSS:** Все новые стили должны быть аккуратно добавлены в `styles.css`. + +## 4. Ограничения + +* **Отсутствие рекурсии в шаблонных ссылках (`@{...}`):** Промпт не может ссылаться на себя или на промпт, который явно или косвенно ссылается на него. Система должна обнаружить подобные попытки и выдать ошибку. (Текущее требование - только 1 уровень вложенности, что фактически исключает рекурсию) +* **Снапшоты:** Отложенная функциональность. +* **Предпросмотр контента:** Отложенная функциональность для клика по Reference Box. + +--- +**TODO:** (Для будущих итераций) + +* Реализовать сохранение снапшотов файлов в базе данных. +* Добавить UI для предпросмотра содержимого Reference Box при клике. +* Улучшить обработку ошибок (уведомления пользователю). +* Оптимизация производительности для очень больших хранилищ с множеством файлов. +* Поддержка других типов файлов (изображения, PDF) - раскрытие метаданных или ссылки на файл. +* Управление версиями промптов, история изменений. \ No newline at end of file