Pin notes to a chat, and import notes from files

Two additions to the shared notes, both about getting content in and out of
the prompt.

Per-chat pinning. Notes normally reach the model as a title list only, and
the body arrives just if the model decides to call read_note. A 📌 on the tab
now puts a page's full body in the system prompt for the chat that is open,
every turn, no tool round trip. The selection is per session (new table
session_note_pages, unique on session_id + page_id), so different
conversations carry different pages. The title list marks pinned pages so the
model does not read them twice, and bodies are capped per page by
SESSION_NOTES_CONTENT_LIMIT.

A new chat has no session row until its first message, so the front end
cannot PUT the selection yet. POST /chat/stream therefore accepts
note_page_ids and applies it before building the context, which makes the
pins count from the very first turn.

File import. Dropping .md/.txt on the editor - or picking them with the new
⬆ button - creates pages, and a .zip is unpacked into one page per text
entry with the first path component as the section. That is exactly the
shape the export writes, so a downloaded zip round-trips back in. Titles that
collide get a " (2)" suffix rather than overwriting, since restoring a backup
into a live workspace should not destroy anything. UploadFile needs
python-multipart, added to the lockfile.

Toasts grew a kind: the import success message was rendering in the red error
toast, as was the existing session-import message. Both are green now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 16:04:41 +09:00
co-authored by Claude Opus 5
parent 216d38c7bd
commit 0e58a07af4
18 changed files with 629 additions and 33 deletions
+6 -1
View File
@@ -28,10 +28,15 @@ async def get_context_messages(db: DBSession, session_id: str) -> list[dict]:
context.append({"role": "system", "content": knowledge_context})
# 共有ノートは「タイトル一覧」だけを常時見せ、本文は read_note ツールで読ませる
notes_context = notes.get_notes_context(db)
notes_context = notes.get_notes_context(db, session_id)
if notes_context:
context.append({"role": "system", "content": notes_context})
# ただしユーザーがこのセッションに紐付けたページは、本文もそのまま載せる
session_notes_context = notes.get_session_notes_context(db, session_id)
if session_notes_context:
context.append({"role": "system", "content": session_notes_context})
if messages:
latest_user_message = next((m.content for m in reversed(messages) if m.role == "user"), "")
local_kb_context = await local_knowledge.get_local_kb_context(db, latest_user_message)