feat: persist task lane across submits and session reloads
Task lane questions/actions are now saved to a pending_task_lane JSONB column on ai_sessions, restoring them on session switch or page reload. Partial submit no longer force-clears the lane — the AI response controls what stays. Also removes redundant "New Session" button from the sidebar (dashboard already provides this). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
30
backend/alembic/versions/fc01_add_pending_task_lane.py
Normal file
30
backend/alembic/versions/fc01_add_pending_task_lane.py
Normal file
@@ -0,0 +1,30 @@
|
||||
"""add pending_task_lane to ai_sessions
|
||||
|
||||
Revision ID: fc01a1b2c3d4
|
||||
Revises: fb1481317ff6
|
||||
Create Date: 2026-03-27
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
|
||||
revision = "fc01a1b2c3d4"
|
||||
down_revision = "fb1481317ff6"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column(
|
||||
"ai_sessions",
|
||||
sa.Column(
|
||||
"pending_task_lane",
|
||||
JSONB,
|
||||
nullable=True,
|
||||
comment="Current task lane state: {questions: [...], actions: [...]}",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column("ai_sessions", "pending_task_lane")
|
||||
@@ -209,6 +209,10 @@ class AISession(Base):
|
||||
JSONB, nullable=False, default=list,
|
||||
comment="Full LLM message history for context continuity",
|
||||
)
|
||||
pending_task_lane: Mapped[Optional[dict[str, Any]]] = mapped_column(
|
||||
JSONB, nullable=True,
|
||||
comment="Current task lane state: {questions: [...], actions: [...]}",
|
||||
)
|
||||
|
||||
# ── Branching ──
|
||||
is_branching: Mapped[bool] = mapped_column(
|
||||
|
||||
@@ -228,6 +228,7 @@ class AISessionDetail(AISessionSummary):
|
||||
ticket_data: dict[str, Any] | None = None
|
||||
steps: list[AISessionStepResponse] = []
|
||||
conversation_messages: list[dict[str, Any]] = [] # Chat sessions store messages here
|
||||
pending_task_lane: dict[str, Any] | None = None
|
||||
is_branching: bool = False
|
||||
active_branch_id: str | None = None
|
||||
|
||||
|
||||
@@ -286,6 +286,15 @@ async def send_chat_message(
|
||||
except Exception:
|
||||
logger.exception("Failed to create fork within branch for session %s", session.id)
|
||||
|
||||
# Persist task lane state on session
|
||||
if branch_questions_data or branch_actions_data:
|
||||
session.pending_task_lane = {
|
||||
"questions": branch_questions_data or [],
|
||||
"actions": branch_actions_data or [],
|
||||
}
|
||||
else:
|
||||
session.pending_task_lane = None
|
||||
|
||||
suggested_flows = extract_suggested_flows(
|
||||
await rag_search(query=message, account_id=account_id, db=db, limit=8)
|
||||
)
|
||||
@@ -393,6 +402,15 @@ async def send_chat_message(
|
||||
logger.exception("Failed to create fork for session %s", session_id)
|
||||
# Fork failed but chat message still sent — don't break the response
|
||||
|
||||
# Persist task lane state on session
|
||||
if questions_data or actions_data:
|
||||
session.pending_task_lane = {
|
||||
"questions": questions_data or [],
|
||||
"actions": actions_data or [],
|
||||
}
|
||||
else:
|
||||
session.pending_task_lane = None
|
||||
|
||||
suggested_flows = extract_suggested_flows(rag_results)
|
||||
|
||||
return display_content, suggested_flows, session, fork_metadata, actions_data, questions_data
|
||||
|
||||
Reference in New Issue
Block a user