Dialer docsPredictive engine
Home Progressive Predictive Callback Disposition API Socket Dashboard

Predictive engine

Customers ring first. Agents join only on answer.

Same dialer_master_data and dialer_priority pool as Progressive. Originate is AMI, not call.php. Lead ingest lives in the API reference.

Customer first Skill-matched bridge Ratio pacing priority 1–3 wait on time

End-to-end flow

A 1 second pacer counts idle skilled agents on this module’s dialer_employee roster, claims unassigned leads from the master table, and originates the customer on a Local channel. Skills come from dialer_employee.skills (JSON list matched to lead form_type). Pinned leads (agent_id = dialer_employee.id) are claimed only for that agent, not from the overdial pool. AMI ignores non-roster extensions. The agent panel stays on waiting until a customer answers and is bridged.

Predictive dialer end-to-end flow

Pacing

target = min(max(idle, floor(idle × predictive_ratio)), max_lines). Extra legs are target − (ringing + on-hold). Ratio is at least 1. There is no abandon-rate brake. After a connected call the agent is not idle until buffer_time wrap finishes. Dashboard On hold is the count of answered customers still on MusicOnHold.

Claim order

Same SQL as Progressive: FOR UPDATE SKIP LOCKED, then Calling and reserved. Pool claims keep agent_id at 0 until a human is actually bridged. Any master row with agent_id is claimed only when that agent is idle and is bridged only to them — it never enters the skill pool.

1
Priority number
Lowest priority_no first.
2
Dial status
Pending, then Callback, then Abandoned, then Not Connected.
3
Age
Never attempted first, then oldest attempt, then oldest push, then lowest id.

Received, Rejected, Calling, and reserved rows are skipped. Abandoned and Not Connected wait on next_retry_at (2-2-1 + working hours). Claim refuses originate outside the work window except for a due callback. priority_id 1, 2, or 3 wait on callback_scheduled_at. Pinned leads (agent_id set) are documented in the Callback Request guide.

AMI originate

Customer originate is Local/{0number}@from-internal/n with Application: MusicOnHold and OLI_ID. AMI_OUTBOUND_CHANNEL (for example PJSIP/9001) identifies the trunk in AMI events; it is not the Originate channel. 10-digit numbers get a leading 0.

When a customer answers, the engine originates PJSIP/{extension} with Application: Bridge. agent_id is written only after that bridge succeeds.

Hold until agent

If nobody matching the skill is free, or the agent is already on another predictive call, the extra customer stays on MusicOnHold. Only one bridge originate is sent to an agent at a time. If that agent declines (SIP deny), the customer is hung up and that extension is not re-offered for the same hold. Waiting legs are drained when another eligible agent becomes idle. Hold is capped by hold_timeout_seconds on fic_dialer_config (default 30). Only then is the customer hung up and the lead settled Abandoned.

Hangup results

HangupStored status
Answered and talkedReceived (keeps agent_id)
Answered, hold timeout / customer left before an agentAbandoned
Cancel by customer, invalid destinationRejected
No answer, busy, congestion, chanunavailNot Connected

Abandoned and Not Connected use the same 2-2-1 scheduler as Progressive: retry_pattern (default [2,2,1]), same-day retry_seconds, snap to next work_start after work_end. Final Disposal only when call_count reaches max_tries. Received, Rejected, and Disposed are not claimed again. Pinned callbacks keep agent_id and use the same retry policy.

Engine config

SettingWhereMeaning
dialer_typefic_dialer_configSet to Predictive
buffer_timefic_dialer_configWrap after a connected call
predictive_ratiofic_dialer_configCustomer legs per idle agent (default 1.20)
hold_timeout_secondsfic_dialer_configMax customer wait on hold (default 30)
max_linesfic_dialer_configCap on ringing + hold customer legs
max_triesfic_dialer_configHard cap on originates (keep in sync with sum of retry_pattern)
retry_secondsfic_dialer_configSame-day gap after Not Connected or Abandoned
retry_patternfic_dialer_configPer working-day caps, default [2,2,1]
work_start / work_endfic_dialer_configOriginate window, default 09:30–18:30 IST
work_daysfic_dialer_configISO weekdays, default Mon–Sat [1,2,3,4,5,6]
AMI_OUTBOUND_CHANNEL.envTrunk identity, e.g. PJSIP/9001
AMI_AGENT_CHANNEL.envDefault PJSIP/{extension}
PREDICTIVE_CONNECT_TIMEOUT_MS.envAgent ring / answer window (default 30s)
CALL_API_URL.envNot used in this mode