# content_publish

## Что делает

Публикует файл из директории текущей сессии для просмотра пользователем прямо в чате. Поддерживаются интерактивные viewer'ы для 3D-моделей (STL, glTF/GLB), HTML-страниц, SVG, PDF, изображений, видео, аудио и текстовых/исходных файлов.

Важно: `workspace/` и директория сессии — разные места.

- `workspace/` — постоянная приватная рабочая зона Нави для черновиков, скриптов, заметок, промежуточных данных и файлов, которые могут пригодиться позже.
- `session_files/{session_id}/` — временная зона конкретной сессии для загруженных пользователем файлов и артефактов, которые пользователь должен увидеть в чате.
- `content_publish` публикует только файлы из директории текущей сессии. Он не копирует файлы из `workspace/`.
- Если нужен только download link для файла из `workspace/`, используйте `share_file`: он сам копирует файл в директорию сессии. Если нужен inline viewer, файл должен оказаться в директории сессии, а затем его нужно зарегистрировать через `content_publish`.

## Как работает внутри

1. **Файл уже должен быть в директории сессии** (`session_files/{session_id}/` по умолчанию; точный корень задаёт `SESSION_FILES_DIR`).
2. Инструмент **не копирует** файл — он только регистрирует метаданные в базе данных.
3. Пользователь видит файл по URL `/sessions/{session_id}/files/{filename}`.
4. Если вы отредактируете файл после публикации, пользователь увидит изменения **сразу** (перезагружать страницу не нужно).
5. Опубликованные файлы остаются доступными в панели Artifacts, поэтому повторная публикация не нужна только для того, чтобы снова показать карточку ниже в диалоге.

## Формат вызова

```python
content_publish(
    filename="мой_файл.svg",      # обязательно — имя файла в директории сессии
    title="Моя диаграмма",        # опционально — заголовок карточки
    content_type="svg",           # опционально — тип для viewer (автоопределение по расширению)
    source_filename="model.scad"  # опционально — исходник для STL, если .scad файл есть в той же директории
)
```

## Где находится директория сессии

Директория сессии — это `session_files/{session_id}/` по умолчанию. Полный путь зависит от настройки `SESSION_FILES_DIR`.

**Как узнать путь:**
```
filesystem info session_files/{session_id}
```

Если `content_publish` не нашёл файл, он вернёт точный путь директории текущей сессии. Доверяйте этому пути и пишите/копируйте файл туда.

## Типичный workflow

### 1. Создание и публикация

```
# Создать SVG в директории сессии
filesystem write session_files/sess-abc/chart.svg "<svg>...</svg>"

# Опубликовать
content_publish(filename="chart.svg", title="Диаграмма продаж")
```

### 2. Редактирование после публикации

```
# Прочитать текущий файл
filesystem read session_files/sess-abc/chart.svg

# Отредактировать
filesystem write session_files/sess-abc/chart.svg "<svg>...исправлено...</svg>"
```

Пользователь увидит изменения через ту же карточку и панель Artifacts — URL не меняется, повторно вызывать `content_publish` не нужно.

## Поддерживаемые типы

| Расширение | `content_type` | Viewer |
|---|---|---|
| `.stl` | `stl` | Three.js, по расширению файла |
| `.glb`, `.gltf` | `model` | тот же Three.js viewer (GLTFLoader) |
| `.html`, `.htm` | `html` | iframe |
| `.svg` | `svg` | iframe |
| `.pdf` | `pdf` | iframe |
| `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.bmp`, `.avif`, `.ico` | `image` | img, по клику — на весь экран |
| `.mp4`, `.webm`, `.mov`, `.mkv`, `.m4v`, `.ogv` | `video` | video |
| `.mp3`, `.wav`, `.ogg`, `.oga`, `.opus`, `.m4a`, `.flac`, `.aac`, `.weba` | `audio` | audio-плеер |
| `.txt`, `.md`, `.log`, `.csv`, `.json`, `.yaml`, `.xml`, `.py`, `.js`, `.ts`, `.scad` и другие текстовые/исходные | `text` | подсвеченный `<pre>` (первые 1 МБ) |

Для неизвестных типов показывается карточка со ссылкой на скачивание.

### Как определяется тип

Тип определяет `navi/content_types.py` — сначала по расширению, затем по сигнатуре файла. Поэтому файл с неверным расширением всё равно открывается правильным viewer'ом: PNG, сохранённый как `.txt`, — изображение; переименованный `.mp3` — аудио; `.ts`, который не является MPEG-транспортным потоком, — текст (TypeScript), а не видео.

Параметр `content_type` нужен только если автоопределение ошиблось; значение вне поддерживаемого списка игнорируется, и тип определяется по файлу. Передавать `content_type="unknown"` бессмысленно.

Графический контент (изображение, SVG, HTML, PDF, 3D-модель, видео) можно развернуть на весь экран кнопкой в шапке карточки и в панели Artifacts.

**glTF:** надёжно работает `.glb` — буферы и текстуры внутри файла. `.gltf`, ссылающийся на отдельные `.bin` и изображения, отрендерится только если все эти файлы тоже лежат в директории сессии (публикуется при этом только сам `.gltf`).

## Просмотр исходников

Для `.svg` и `.html` пользователь может открыть исходник прямо из карточки/панели Artifacts — отдельный параметр не нужен, потому что опубликованный файл сам является исходником.

Для `.stl` можно передать `source_filename`, если модель была создана из OpenSCAD и `.scad` файл лежит в той же директории сессии:

```
content_publish(filename="part.stl", title="Деталь", content_type="stl", source_filename="part.scad")
```

Если STL был скачан или исходного `.scad` нет, просто не передавайте `source_filename`. Это нормальная ситуация и не ошибка.

## Важные правила

1. **Файл должен существовать ДО вызова** — `content_publish` не создаёт файлы, только регистрирует.
2. **Не публикуйте напрямую из `workspace/`** — сначала поместите финальный файл в директорию текущей сессии.
3. **Проверяйте коллизии** — если файл с таким именем уже есть, запись публикации будет обновлена, а файл останется тем же путём.
4. **Используйте понятные имена** — `chart.svg` лучше чем `file_1.svg`.
5. **Для редактирования используйте тот же путь** — не создавайте новые копии, правьте оригинал в директории сессии.
6. **Не дублируйте опубликованный контент в текстовом ответе** — `content_publish` уже отображает файл пользователю в чате в виде интерактивной карточки и в панели Artifacts. После вызова `content_publish` не вставляйте SVG-код, HTML-разметку, base64-изображения, screenshots, iframe/markdown preview или вторую визуальную копию результата в текст сообщения. В текстовом ответе достаточно краткого подтверждения и не-визуальных пояснений.
7. **Не публикуйте повторно ради видимости** — если карточка ушла выше по диалогу, пользователь всё равно найдёт файл в панели Artifacts. Для обновления содержимого правьте тот же файл в директории сессии.
8. **Повторная публикация допустима осознанно** — используйте её для нового файла или если нужно обновить метаданные публикации, например `title` или `content_type`.
9. **STL source опционален** — передавайте `source_filename` только если реальный `.scad` исходник существует в директории сессии. Не выдумывайте путь и не считайте отсутствие исходника ошибкой.
