feat(maint+ai): OTP modal agent picker + supervisor AI quick actions

Maint shortcuts (Unlock Agent / Force Ready) used to read agentId from the CC-agent's localStorage config — supervisors had no such config and the endpoint 400'd. New flow: after OTP passes, modal calls /api/maint/session-status and renders a two-bucket picker (Locked selectable / Free informational 'Already free'). Orphan locks surface with an explicit label.

- use-maint-shortcuts: agentPickerEndpoint flag on forceReady + unlockAgent
- maint-otp-modal: two-phase — OTP gate, then picker, then submit; OTP
  held in state across phases so the operator doesn't re-enter it

AI chat panel: supervisor context now shows supervisor-appropriate quick actions (Agent performance / Call summary / Campaign stats / Who needs attention?) that map 1:1 to the supervisor tool set on the sidecar. Agent flow keeps the theme-token quick actions (doctors/clinics/packages).
This commit is contained in:
2026-04-15 18:56:34 +05:30
parent 00c28e642b
commit 9d09662f16
3 changed files with 213 additions and 45 deletions

View File

@@ -5,6 +5,10 @@ export type MaintAction = {
label: string;
description: string;
needsPreStep?: boolean;
// When set, after OTP passes the modal calls this endpoint to fetch
// `{ locked, free }` agent buckets and shows a picker. Confirm then
// POSTs to `endpoint` with { agentId } from the selection.
agentPickerEndpoint?: string;
clientSideHandler?: (payload: any) => Promise<{ status: string; message: string }>;
};
@@ -13,11 +17,13 @@ const MAINT_ACTIONS: Record<string, MaintAction> = {
endpoint: 'force-ready',
label: 'Force Ready',
description: 'Logout and re-login the agent to force Ready state on Ozonetel.',
agentPickerEndpoint: 'session-status',
},
unlockAgent: {
endpoint: 'unlock-agent',
label: 'Unlock Agent',
description: 'Release the Redis session lock so the agent can log in again.',
agentPickerEndpoint: 'session-status',
},
backfill: {
endpoint: 'backfill-missed-calls',