feat: two-phase resolve with streaming ticket notes generation

ConcludeSessionModal now resolves instantly (Phase 1) then streams
ticket notes via SSE (Phase 2), with skeleton loading and fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-03-28 23:08:25 +00:00
parent bcab8158ab
commit 5e04aad16f
2 changed files with 108 additions and 38 deletions

View File

@@ -396,21 +396,19 @@ export default function AssistantChatPage() {
const handleConclude = async (outcome: ConclusionOutcome, _notes: string): Promise<string> => {
if (!activeChatId) throw new Error('No active chat')
// Map conclusion outcomes to ai_sessions actions
if (outcome === 'resolved') {
const result = await aiSessionsApi.resolveSession(activeChatId, {
await aiSessionsApi.resolveSession(activeChatId, {
resolution_summary: _notes || 'Resolved via assistant chat',
})
return result.documentation?.problem_summary || 'Session resolved'
return activeChatId
} else if (outcome === 'escalated') {
const result = await aiSessionsApi.escalateSession(activeChatId, {
await aiSessionsApi.escalateSession(activeChatId, {
escalation_reason: _notes || 'Escalated from assistant chat',
})
return result.documentation?.problem_summary || 'Session escalated'
return activeChatId
} else {
// paused
await aiSessionsApi.pauseSession(activeChatId)
return 'Session paused'
return activeChatId
}
}
@@ -830,6 +828,7 @@ export default function AssistantChatPage() {
onConclude={handleConclude}
onResumeNew={handleResumeNew}
chatTitle={chats.find(c => c.id === activeChatId)?.title ?? 'Chat'}
sessionId={activeChatId}
/>
</div>
</>