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:
+44
-1
@@ -15,10 +15,15 @@ SSE でストリーミング応答を返す。
|
||||
{
|
||||
"message": "こんにちは",
|
||||
"session_id": "uuid(省略時は新規セッション作成)",
|
||||
"model": "gpt-5.4(省略時は DEFAULT_MODEL)"
|
||||
"model": "gpt-5.4(省略時は DEFAULT_MODEL)",
|
||||
"note_page_ids": [1, 2]
|
||||
}
|
||||
```
|
||||
|
||||
`note_page_ids` は「このセッションで本文をシステムプロンプトに載せる共有ノートのページ ID」。
|
||||
渡すとコンテキスト組み立ての前にサーバー側の指定を丸ごと置き換える(`PUT /chat/sessions/{id}/notes` と同じ内容)。
|
||||
新規セッションではフロントがまだ session_id を持てないため、初回はここでしか指定できない。省略すると現在の指定を変更しない。
|
||||
|
||||
**SSE イベント**
|
||||
| type | value | タイミング |
|
||||
|---|---|---|
|
||||
@@ -64,6 +69,28 @@ SSE でストリーミング応答を返す。
|
||||
|
||||
---
|
||||
|
||||
### GET /chat/sessions/{session_id}/notes
|
||||
このセッションで本文をシステムプロンプトに載せるよう指定された共有ノートのページ ID を返す。
|
||||
順序はノートのタブ順(`position`)。セッションが無ければ `404`。
|
||||
|
||||
**レスポンス**
|
||||
```json
|
||||
{ "page_ids": [1, 2] }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PUT /chat/sessions/{session_id}/notes
|
||||
指定を丸ごと置き換える。存在しないページ ID は黙って捨てられ、実際に紐付いた ID が返る。
|
||||
空配列を渡すと全解除。セッションが無ければ `404`。
|
||||
|
||||
**リクエスト**
|
||||
```json
|
||||
{ "page_ids": [1, 2] }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### DELETE /chat/sessions/{session_id}
|
||||
セッションと紐づくメッセージ・メモリをすべて削除。`204 No Content` を返す。
|
||||
|
||||
@@ -187,6 +214,22 @@ SSE でストリーミング応答を返す。
|
||||
|
||||
---
|
||||
|
||||
### POST /api/notes/import
|
||||
`multipart/form-data` の `files` でアップロードされたファイルをページとして取り込み、
|
||||
`201 Created` で作成したページの配列を返す。
|
||||
|
||||
| 拡張子 | 取り込み方 |
|
||||
|---|---|
|
||||
| `.md` / `.markdown` / `.txt` / `.text` | 1 ファイル 1 ページ。タイトルはファイル名から拡張子と `01_` 形式の通し番号を落としたもの |
|
||||
| `.zip` | 中のテキストファイルを 1 つずつページにする。第 1 階層のフォルダ名がセクションになる(`GET /api/notes/export` の ZIP をそのまま戻せる) |
|
||||
|
||||
- 既存ページとタイトルが衝突したら `タイトル (2)` のように連番を足して**別ページとして作る**(上書きはしない)
|
||||
- 文字コードは UTF-8 (BOM 可) → CP932 の順に試す
|
||||
- 対象外の拡張子・`NOTES_IMPORT_MAX_BYTES`(既定 2,000,000)超のファイル・`NOTES_IMPORT_MAX_PAGES`(既定 100)を超えた分・壊れた ZIP は**黙って飛ばす**
|
||||
- 1 ページも取り込めなかった場合のみ `400`
|
||||
|
||||
---
|
||||
|
||||
### GET /api/notes/export
|
||||
全ページを ZIP でダウンロードさせる(`Content-Disposition: attachment`)。
|
||||
1 ページ 1 ファイルの Markdown で、本文はそのまま。エントリ名は `<セクション>/<通し番号>_<タイトル>.md`
|
||||
|
||||
Reference in New Issue
Block a user