历史记录回显

This commit is contained in:
董宏凯 committed 2026-05-17 22:55:01 +08:00
1 parent 52ba178c4e
commit 0af8ca5f78
7 files changed
+155 -33

No files matched your search

@@ -63,6 +63,11 @@ class RenameSessionRequest(BaseModel):
title: str
class SaveTranscriptRequest(BaseModel):
# 前端组装的完整对话时间线(progressEvents + completedInterventions)
transcript: dict
class ArticleTypeRequest(BaseModel):
key: str
label: str
@@ -103,6 +108,7 @@ class SessionResponse(BaseModel):
draft_markdown: Optional[str] = None
completed_interventions: Optional[list] = None
review_result: Optional[dict] = None
transcript: Optional[dict] = None
created_at: str
updated_at: str
@@ -285,6 +291,21 @@ async def delete_session(session_id: str, request: Request):
return {"success": True}
@router.put("/sessions/{session_id}/transcript")
async def save_transcript(session_id: str, body: SaveTranscriptRequest, request: Request):
"""保存会话的完整对话时间线,供历史会话回显出与实时对话一致的富时间线。"""
from app.gateway.deps import get_ai_writing_session_store, get_current_user
repo = get_ai_writing_session_store(request)
if repo is None:
return {"success": False}
user_id = await get_current_user(request)
updated = await repo.update(session_id, user_id=user_id, transcript=body.transcript)
if updated is None:
raise HTTPException(status_code=404, detail="Session not found")
return {"success": True}
@router.get("/article-types", response_model=list[ArticleTypeResponse])
async def list_article_types(request: Request):
"""列出所有文章类型,按 sort_order 升序排列。"""
@@ -22,5 +22,7 @@ class AIWritingSessionRow(Base):
draft_markdown: Mapped[str | None] = mapped_column(Text, nullable=True)
completed_interventions: Mapped[str | None] = mapped_column(Text, nullable=True) # JSON array
review_result: Mapped[str | None] = mapped_column(Text, nullable=True) # JSON object
# 完整对话时间线(前端组装的 progressEvents + completedInterventions),用于历史回显
transcript: Mapped[str | None] = mapped_column(Text, nullable=True) # JSON object
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(UTC))
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(UTC))
@@ -24,7 +24,7 @@ class AIWritingSessionRepository:
for k in ("created_at", "updated_at"):
if isinstance(d.get(k), datetime):
d[k] = d[k].isoformat()
for k in ("completed_interventions", "review_result"):
for k in ("completed_interventions", "review_result", "transcript"):
val = d.get(k)
if isinstance(val, str):
try:
@@ -53,6 +53,7 @@ class AIWritingSessionRepository:
draft_markdown=None,
completed_interventions=None,
review_result=None,
transcript=None,
created_at=now,
updated_at=now,
)
@@ -73,6 +74,7 @@ class AIWritingSessionRepository:
draft_markdown=_UNSET,
completed_interventions=_UNSET,
review_result=_UNSET,
transcript=_UNSET,
) -> dict | None:
resolved_user_id = resolve_user_id(user_id, method_name="AIWritingSessionRepository.update")
async with self._sf() as session:
@@ -101,6 +103,12 @@ class AIWritingSessionRepository:
if review_result is not None
else None
)
if transcript is not _UNSET:
row.transcript = (
json.dumps(transcript, ensure_ascii=False)
if transcript is not None
else None
)
row.updated_at = datetime.now(UTC)
await session.commit()
await session.refresh(row)
@@ -0,0 +1,39 @@
"""Add transcript column to ai_writing_sessions.
存储前端组装的完整对话时间线(progressEvents + completedInterventions),
供历史会话回显出与实时对话一致的富时间线。
Revision ID: 20260517_03
Revises: 20260517_02
Create Date: 2026-05-17
"""
from __future__ import annotations
import sqlalchemy as sa
from alembic import op
from sqlalchemy import inspect
revision = "20260517_03"
down_revision = "20260517_02"
branch_labels = None
depends_on = None
def _has_column(table_name: str, column_name: str) -> bool:
inspector = inspect(op.get_bind())
if table_name not in inspector.get_table_names():
return False
return any(col["name"] == column_name for col in inspector.get_columns(table_name))
def upgrade() -> None:
if _has_column("ai_writing_sessions", "transcript"):
return
op.add_column("ai_writing_sessions", sa.Column("transcript", sa.Text, nullable=True))
def downgrade() -> None:
if _has_column("ai_writing_sessions", "transcript"):
op.drop_column("ai_writing_sessions", "transcript")