From 1bf62ebe4badb717ad5cdd4ae2c2bab17c6957d2 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 2 Jun 2026 16:43:17 +0600 Subject: [PATCH] =?UTF-8?q?[2026-06-02]=20session-design:=20=D0=BF=D0=BB?= =?UTF-8?q?=D0=B0=D0=BD=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=2012.1-12.3,=20ge?= =?UTF-8?q?nerateSessionInsight=20=E2=86=92=20full=20agentic=20analysis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../psychologist-app/session-design.md | 69 ++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/personal/projects/psychologist-app/session-design.md b/personal/projects/psychologist-app/session-design.md index bc7823a7..6dc56c85 100755 --- a/personal/projects/psychologist-app/session-design.md +++ b/personal/projects/psychologist-app/session-design.md @@ -526,6 +526,74 @@ func startSession() { --- +--- + +## 12. План работ — актуальный (обновлено 2026-06-02) + +### 12.1 Реализовано ✅ + +- `AnalystResponse.sessionComplete: Bool` + AnalystJSON backward-compatible +- `ProcessingResult.readyToClose([String]?, observation:)` +- `SessionManager.userTurnCount`, `consecutiveShortAnswerCount`, hard limit 8 ходов +- `SessionManager.continueSession()`, `detectIncompleteSession()`, `resumeOrStart()` +- `FatigueContext`, `IncompleteSessionState`, `SessionResumeResult` +- NarratorBot: legit-маркер, injection guard, off-topic директива, детекция настроения/усталости +- AnalystBot: turnCount/startTime/duration/messageCount/fatigueCtx → user message; пейсинг-правила в systemPrompt +- SessionViewModel: `showCompletionPrompt`, `showCompletionCard()`, `continueAfterCompletion()` +- CardData: `isCompletion: Bool` +- 182 теста, 0 фейлов + +### 12.2 Ближайшие задачи + +#### A. UI-связка карточки завершения (5 строк) +`onQuickReply` в SessionView: если `card.isCompletion` → "Завершить" → `endSession()`, "Продолжить" → `continueAfterCompletion()`. Без этого карточка есть, но кнопки не работают. + +#### B. Session Recovery при входе (~20 строк) +Заменить `startSession()` на `resumeOrStart()` при открытии SessionView. При `.resumed` — восстановить карточки из `session.messages` (видимые .analyst сообщения). При `.startedAfterPartialSummary` — показать "В прошлый раз..." первой карточкой. + +#### C. UX: одна карточка + growing input [НОВОЕ] +- Одна карточка одновременно на экране (не список) +- При открытии клавиатуры карточка уходит вверх над орбом, не скрывается +- Поле ввода: `TextEditor` с `axis: .vertical`, растёт по мере набора, word-wrapped + +#### D. generateSessionInsight — полный анализ с инструментами [ОБЯЗАТЕЛЬНО] + +**Проблема:** сейчас `generateSessionInsight()` — простой `introService.complete()` (Haiku, один вызов без инструментов, с обрезкой контента). Никакой связи с историей сессий. + +**Требование:** агент анализирует ВСЮ сессию, без программной обрезки, с доступом к прошлым сессиям для сравнения паттернов. + +**Реализация:** +- Заменить `introService.complete()` на `analystBot.completeWithTools()` (те же инструменты: `search_sessions`, `read_session`, `get_index`, `read_profile`) +- Передавать полный диалог текущей сессии (все сообщения user + analyst) +- Промпт: синтез инсайта + сравнение с паттернами из прошлых сессий +- Контекстного окна Sonnet (200k) достаточно для любой бытовой сессии без chunking +- Chunking как крайний fallback только если диалог > ~150k символов + +**Что меняется в data flow:** +``` +Было: generateSessionInsight → Haiku.complete(prefix_500_chars) → строка +Стало: generateSessionInsight → Sonnet.completeWithTools(full_dialogue + tools) → строка + ↳ может вызвать search_sessions("паттерн X") → сравнить с прошлым + ↳ может вызвать read_profile() → уточнить контекст + ↳ возвращает инсайт с учётом всей истории +``` + +#### E. insights.md — финальный инсайт не записывается [БАГ] +`saveSessionToProfile()` пишет в `observations/Www.md` и `index.md`, но **не вызывает** `ProfileManager.appendInsight()`. Итог: `insights.md` (который читает AnalystBot через `read_profile`) не обновляется после сессии. Добавить одну строку в `saveSessionToProfile()`. + +#### F. insights.md — suggestedInsight по ходу диалога [БАГ] +`suggestedInsight` от аналитика добавляется в `session.insights` (в памяти), но в `insights.md` не пишется до конца сессии. Если сессия прервана через X — инсайт теряется. Писать немедленно при получении. + +### 12.3 Следующая итерация + +- mood_delta → Orb visual feedback (Section 9.4) +- save_session app API tool для агента (Section 7.5) +- Vault sync архитектура: on-device → vault отдельным job (Section 11.4) +- Retention protocol при пропущенных сессиях (Section 5) +- Android Skip совместимость новых типов + +--- + ## 6. Открытые вопросы - [ ] Как именно Narrator детектирует что вопросы в 3-м лице и нужно переформулировать? Prompt rule или регекс-паттерн? @@ -536,7 +604,6 @@ func startSession() { - [ ] mood_delta — достаточно ли 3 значений, нужна ли шкала -2..+2? - [ ] Vault sync архитектура: когда/как экспортировать on-device сессии в vault, чтобы агент не имел прямого доступа к ФС мака? -- [ ] generateSessionInsight: заменить prefix(500) на полный диалог с token-truncation? ## Связанные заметки