Files
playchat/backend/app/api/notes.py
T
colcaroliandClaude Opus 5 a08b1785a4 Add shared notes with tabbed pages editable by user and AI
Adds a note_pages table backing a tabbed notes panel where the user and
the model can both read and write. Only page titles (plus a short
preview) are injected into the system prompt on every turn; full page
content is kept out of context and fetched on demand via a read_note
tool, with write_note letting the model append to, replace, or create a
page.

Generalizes llm.resolve_web_search into resolve_tool_calls so the
tool-calling loop handles web_search and the new note tools through one
path. The chat stream emits a notes_updated SSE event when the model
edits a note so the frontend panel can refresh; local edits are tracked
as dirty and never clobbered by that refresh.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 01:27:31 +09:00

74 lines
2.0 KiB
Python

from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy.orm import Session as DBSession
from app.core.notes import next_position
from app.db.database import get_db
from app.db.models import NotePage
router = APIRouter(prefix="/api/notes", tags=["notes"])
class NotePageResponse(BaseModel):
id: int
title: str
content: str
position: int
updated_at: datetime
class Config:
from_attributes = True
class NotePageCreate(BaseModel):
title: str = "新しいページ"
content: str = ""
class NotePageUpdate(BaseModel):
title: str | None = None
content: str | None = None
@router.get("", response_model=list[NotePageResponse])
def list_pages(db: DBSession = Depends(get_db)):
return db.query(NotePage).order_by(NotePage.position, NotePage.id).all()
@router.post("", response_model=NotePageResponse, status_code=201)
def create_page(req: NotePageCreate, db: DBSession = Depends(get_db)):
title = req.title.strip() or "新しいページ"
page = NotePage(title=title, content=req.content, position=next_position(db))
db.add(page)
db.commit()
db.refresh(page)
return page
@router.patch("/{page_id}", response_model=NotePageResponse)
def update_page(page_id: int, req: NotePageUpdate, db: DBSession = Depends(get_db)):
page = db.get(NotePage, page_id)
if not page:
raise HTTPException(status_code=404, detail="Note page not found")
if req.title is not None:
title = req.title.strip()
if not title:
raise HTTPException(status_code=400, detail="title is empty")
page.title = title
if req.content is not None:
page.content = req.content
db.commit()
db.refresh(page)
return page
@router.delete("/{page_id}", status_code=204)
def delete_page(page_id: int, db: DBSession = Depends(get_db)):
page = db.get(NotePage, page_id)
if not page:
raise HTTPException(status_code=404, detail="Note page not found")
db.delete(page)
db.commit()