feat: mid-session status updates — ticket notes, client updates, email drafts
Engineers can now generate AI-powered status updates during active FlowPilot
sessions and after resolve/escalate. Three audiences (Ticket Notes, Client
Update, Email Draft) with Quick/Detailed length options. Copy to clipboard
with one click. Client names auto-inserted from intake/PSA context.
Backend: new endpoint POST /ai-sessions/{id}/status-update with audience-aware
system prompts. Frontend: StatusUpdateModal with 2-step selection flow,
Share Update button in action bar, Share Resolution/Escalation on completed
sessions. Also updates Solutions Library spec with Community tier design.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,16 @@
|
||||
import { useState } from 'react'
|
||||
import { CheckCircle2, ArrowUpRight, Pause, X } from 'lucide-react'
|
||||
import { CheckCircle2, ArrowUpRight, Pause, X, FileText } from 'lucide-react'
|
||||
import { EscalateModal } from './EscalateModal'
|
||||
import type { ResolveSessionRequest, EscalateSessionRequest, SessionDocumentation } from '@/types/ai-session'
|
||||
import { StatusUpdateModal } from './StatusUpdateModal'
|
||||
import type {
|
||||
ResolveSessionRequest,
|
||||
EscalateSessionRequest,
|
||||
SessionDocumentation,
|
||||
StatusUpdateAudience,
|
||||
StatusUpdateLength,
|
||||
StatusUpdateContext,
|
||||
StatusUpdateResponse,
|
||||
} from '@/types/ai-session'
|
||||
|
||||
interface FlowPilotActionBarProps {
|
||||
canResolve: boolean
|
||||
@@ -9,10 +18,12 @@ interface FlowPilotActionBarProps {
|
||||
isProcessing: boolean
|
||||
hasPsaTicket?: boolean
|
||||
sessionId?: string
|
||||
canShareUpdate?: boolean
|
||||
onResolve: (data: ResolveSessionRequest) => Promise<SessionDocumentation>
|
||||
onEscalate: (data: EscalateSessionRequest) => Promise<SessionDocumentation>
|
||||
onPause?: () => Promise<void>
|
||||
onAbandon?: () => Promise<void>
|
||||
onGenerateStatusUpdate?: (audience: StatusUpdateAudience, length: StatusUpdateLength, context: StatusUpdateContext) => Promise<StatusUpdateResponse>
|
||||
}
|
||||
|
||||
export function FlowPilotActionBar({
|
||||
@@ -21,14 +32,17 @@ export function FlowPilotActionBar({
|
||||
isProcessing,
|
||||
hasPsaTicket = false,
|
||||
sessionId,
|
||||
canShareUpdate = false,
|
||||
onResolve,
|
||||
onEscalate,
|
||||
onPause,
|
||||
onAbandon,
|
||||
onGenerateStatusUpdate,
|
||||
}: FlowPilotActionBarProps) {
|
||||
const [showResolve, setShowResolve] = useState(false)
|
||||
const [showEscalate, setShowEscalate] = useState(false)
|
||||
const [showAbandon, setShowAbandon] = useState(false)
|
||||
const [showStatusUpdate, setShowStatusUpdate] = useState(false)
|
||||
const [resolutionSummary, setResolutionSummary] = useState('')
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
|
||||
@@ -90,6 +104,17 @@ export function FlowPilotActionBar({
|
||||
<ArrowUpRight size={16} />
|
||||
Escalate
|
||||
</button>
|
||||
{canShareUpdate && onGenerateStatusUpdate && (
|
||||
<button
|
||||
onClick={() => setShowStatusUpdate(true)}
|
||||
disabled={isProcessing}
|
||||
className="flex flex-1 sm:flex-initial items-center justify-center gap-2 rounded-lg bg-cyan-500/10 border border-cyan-500/20 px-4 py-2 min-h-[44px] text-sm font-medium text-cyan-400 hover:bg-cyan-500/20 disabled:opacity-40 disabled:pointer-events-none transition-colors"
|
||||
>
|
||||
<FileText size={16} />
|
||||
<span className="hidden sm:inline">Share Update</span>
|
||||
<span className="sm:hidden">Update</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex gap-2 sm:ml-auto">
|
||||
{onPause && (
|
||||
@@ -184,6 +209,17 @@ export function FlowPilotActionBar({
|
||||
hasPsaTicket={hasPsaTicket}
|
||||
sessionId={sessionId}
|
||||
/>
|
||||
|
||||
{/* Status Update modal */}
|
||||
{onGenerateStatusUpdate && (
|
||||
<StatusUpdateModal
|
||||
open={showStatusUpdate}
|
||||
onClose={() => setShowStatusUpdate(false)}
|
||||
onGenerate={onGenerateStatusUpdate}
|
||||
context="status"
|
||||
hasPsaTicket={hasPsaTicket}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user