@xema/omni-protocol 0.1.38 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +13 -13
- package/dist/index.js +4 -4
- package/dist/validation.js +4 -4
- package/guide.md +44 -39
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -437,8 +437,8 @@ export type TaskCapabilities<C extends Channel = Channel> = C extends "voice" ?
|
|
|
437
437
|
mute?: Lockable<true>;
|
|
438
438
|
hold?: Lockable<true>;
|
|
439
439
|
agentDisconnect?: Lockable<true>;
|
|
440
|
-
/**
|
|
441
|
-
|
|
440
|
+
/** Connect back to the party while `completing`, whoever placed the call; the task returns to `in-progress`. */
|
|
441
|
+
connectBack?: Lockable<true>;
|
|
442
442
|
blindTransfer?: Lockable<true | DestinationDirectory>;
|
|
443
443
|
/** Park the customer and call a destination first; then `complete` or `cancel`. */
|
|
444
444
|
consultTransfer?: Lockable<true | DestinationDirectory>;
|
|
@@ -447,10 +447,10 @@ export type TaskCapabilities<C extends Channel = Channel> = C extends "voice" ?
|
|
|
447
447
|
conference?: Lockable<true | DestinationDirectory>;
|
|
448
448
|
recording?: Lockable<true>;
|
|
449
449
|
} : C extends "chat" ? SharedTaskCapabilities & {
|
|
450
|
-
|
|
450
|
+
decline?: Lockable<true>;
|
|
451
451
|
hold?: Lockable<true>;
|
|
452
452
|
} : SharedTaskCapabilities & {
|
|
453
|
-
|
|
453
|
+
decline?: Lockable<true>;
|
|
454
454
|
};
|
|
455
455
|
/**
|
|
456
456
|
* How a reusing browser's session is keyed.
|
|
@@ -730,9 +730,9 @@ export type TaskOutcome = {
|
|
|
730
730
|
failure: ProtocolFailure;
|
|
731
731
|
};
|
|
732
732
|
export declare const TASK_COMMAND_NAMES: {
|
|
733
|
-
readonly voice: readonly ["answer", "decline", "start-call", "mute", "hold", "resume", "disconnect", "
|
|
734
|
-
readonly chat: readonly ["accept", "
|
|
735
|
-
readonly email: readonly ["accept", "
|
|
733
|
+
readonly voice: readonly ["answer", "decline", "start-call", "mute", "hold", "resume", "disconnect", "connect-back", "transfer", "lead-assist", "conference", "recording", "complete"];
|
|
734
|
+
readonly chat: readonly ["accept", "decline", "pause", "resume", "complete"];
|
|
735
|
+
readonly email: readonly ["accept", "decline", "complete"];
|
|
736
736
|
};
|
|
737
737
|
export type TaskCommandName<C extends keyof typeof TASK_COMMAND_NAMES> = (typeof TASK_COMMAND_NAMES)[C][number];
|
|
738
738
|
export interface DispositionPayload {
|
|
@@ -755,9 +755,9 @@ export type VoiceTaskCommand = {
|
|
|
755
755
|
} | {
|
|
756
756
|
type: "disconnect";
|
|
757
757
|
}
|
|
758
|
-
/** Issuable only in `completing`, under the `
|
|
758
|
+
/** Issuable only in `completing`, under the `connectBack` capability. Dials the party's own number, so it names none. */
|
|
759
759
|
| {
|
|
760
|
-
type: "
|
|
760
|
+
type: "connect-back";
|
|
761
761
|
dialId: DialId;
|
|
762
762
|
}
|
|
763
763
|
/** Blind: hand the customer to `destination` with nobody consulted. Gated by `blindTransfer`. */
|
|
@@ -826,7 +826,7 @@ export type VoiceTaskCommand = {
|
|
|
826
826
|
export type ChatTaskCommand = {
|
|
827
827
|
type: "accept";
|
|
828
828
|
} | {
|
|
829
|
-
type: "
|
|
829
|
+
type: "decline";
|
|
830
830
|
} | {
|
|
831
831
|
type: "pause";
|
|
832
832
|
} | {
|
|
@@ -837,7 +837,7 @@ export type ChatTaskCommand = {
|
|
|
837
837
|
export type EmailTaskCommand = {
|
|
838
838
|
type: "accept";
|
|
839
839
|
} | {
|
|
840
|
-
type: "
|
|
840
|
+
type: "decline";
|
|
841
841
|
} | ({
|
|
842
842
|
type: "complete";
|
|
843
843
|
} & DispositionPayload);
|
|
@@ -1084,8 +1084,8 @@ export type OpenMediaResult = {
|
|
|
1084
1084
|
/**
|
|
1085
1085
|
* What the team may leave to the person: a capability by its own name -- `hold`, `mute` -- or a
|
|
1086
1086
|
* skill by its provider id. The same key as in `Task.capabilities`, because it is the same
|
|
1087
|
-
* capability seen at another level.
|
|
1088
|
-
* team's, on or off, within what the queue allows.
|
|
1087
|
+
* capability seen at another level. Connecting back and a new call are never the person's; they
|
|
1088
|
+
* are the team's, on or off, within what the queue allows.
|
|
1089
1089
|
*/
|
|
1090
1090
|
export type PreferenceId = "hold" | "mute" | `skill:${string}`;
|
|
1091
1091
|
/**
|
package/dist/index.js
CHANGED
|
@@ -71,13 +71,13 @@ export function effectiveLevels(declared) {
|
|
|
71
71
|
// ---------------------------------------------------------------------------
|
|
72
72
|
export const TASK_COMMAND_NAMES = {
|
|
73
73
|
voice: ["answer", "decline", "start-call", "mute", "hold", "resume", "disconnect",
|
|
74
|
-
"
|
|
75
|
-
chat: ["accept", "
|
|
76
|
-
email: ["accept", "
|
|
74
|
+
"connect-back", "transfer", "lead-assist", "conference", "recording", "complete"],
|
|
75
|
+
chat: ["accept", "decline", "pause", "resume", "complete"],
|
|
76
|
+
email: ["accept", "decline", "complete"],
|
|
77
77
|
};
|
|
78
78
|
/** The dial a command places, by the host's identity for it; `undefined` for a command that dials nothing. */
|
|
79
79
|
export function commandDialId(command) {
|
|
80
|
-
if (command.type === "
|
|
80
|
+
if (command.type === "connect-back")
|
|
81
81
|
return command.dialId;
|
|
82
82
|
if (command.type === "transfer" && (command.action === undefined || command.action === "consult"))
|
|
83
83
|
return command.dialId;
|
package/dist/validation.js
CHANGED
|
@@ -73,7 +73,7 @@ const EXPLAINED_FAILURES = ["busy", "no-answer", "unreachable", "rejected", "can
|
|
|
73
73
|
const ON_CALL_ROLES = membersOf({ party: true, agent: true, consulted: true, conferenced: true });
|
|
74
74
|
const ON_CALL_STAGES = membersOf({ ringing: true, joined: true });
|
|
75
75
|
/** The task capabilities under which a command dials, and so need the manifest to say how a dial ends. */
|
|
76
|
-
const DIALLING_CAPABILITIES = ["
|
|
76
|
+
const DIALLING_CAPABILITIES = ["connectBack", "blindTransfer", "consultTransfer", "conference"];
|
|
77
77
|
const SNAPSHOT_REASONS = membersOf({
|
|
78
78
|
reconnected: true, "provider-requested": true,
|
|
79
79
|
});
|
|
@@ -94,10 +94,10 @@ const ISOLATION_SCHEME_VALUES = Object.values(BROWSER_ISOLATION_SCHEMES);
|
|
|
94
94
|
const TASK_CAPABILITIES = {
|
|
95
95
|
voice: membersOf({
|
|
96
96
|
browsers: true, dispositions: true, custom: true, decline: true, mute: true, hold: true,
|
|
97
|
-
agentDisconnect: true,
|
|
97
|
+
agentDisconnect: true, connectBack: true, blindTransfer: true, consultTransfer: true, leadAssist: true, conference: true, recording: true,
|
|
98
98
|
}),
|
|
99
|
-
chat: membersOf({ browsers: true, dispositions: true, custom: true,
|
|
100
|
-
email: membersOf({ browsers: true, dispositions: true, custom: true,
|
|
99
|
+
chat: membersOf({ browsers: true, dispositions: true, custom: true, decline: true, hold: true }),
|
|
100
|
+
email: membersOf({ browsers: true, dispositions: true, custom: true, decline: true }),
|
|
101
101
|
};
|
|
102
102
|
// The published list and the type's keys are the same set, or one of them is wrong.
|
|
103
103
|
true;
|
package/guide.md
CHANGED
|
@@ -35,7 +35,7 @@ are used precisely throughout and mean nothing looser here.
|
|
|
35
35
|
| **Event** | One completed transaction reported after a snapshot established the baseline. |
|
|
36
36
|
| **Break** | A reported, supervised state in which the agent is not working — one with a reason, a decision behind it and a return. It covers what a platform may call *not-ready*, including equipment trouble. An agent who is merely at capacity is not on a break. |
|
|
37
37
|
| **Workspace** | What Omni shows the agent. The **task workspace** holds the selected task, its controls and its browsers; the **idle workspace** holds what a provider contributes when no task is selected — dialpad, contacts, calendar, roster. |
|
|
38
|
-
| **Dial** | One outbound call the host asks a provider to place — from the idle dialpad, a transfer, a conference add, or a
|
|
38
|
+
| **Dial** | One outbound call the host asks a provider to place — from the idle dialpad, a transfer, a conference add, or a connect-back. Identified by the host's `dialId`, accepted as `dialling`, and ended by exactly one `dial-outcome`. See **Every dial has an outcome**. |
|
|
39
39
|
| **On the call** | Who a voice task's audio joins, or is bringing in, as the provider states it on `Task.onCall`: the party, the agents, and anyone consulted or conferenced in from the moment their dial is placed. |
|
|
40
40
|
|
|
41
41
|
Six words describe *what state a thing is in*, and they are not interchangeable: each belongs to
|
|
@@ -476,7 +476,7 @@ type TaskCapabilities<C extends Channel = Channel> =
|
|
|
476
476
|
mute?: Lockable<true>;
|
|
477
477
|
hold?: Lockable<true>;
|
|
478
478
|
agentDisconnect?: Lockable<true>;
|
|
479
|
-
|
|
479
|
+
connectBack?: Lockable<true>;
|
|
480
480
|
blindTransfer?: Lockable<true | DestinationDirectory>;
|
|
481
481
|
consultTransfer?: Lockable<true | DestinationDirectory>;
|
|
482
482
|
leadAssist?: Lockable<true>;
|
|
@@ -484,8 +484,8 @@ type TaskCapabilities<C extends Channel = Channel> =
|
|
|
484
484
|
recording?: Lockable<true>;
|
|
485
485
|
}
|
|
486
486
|
: C extends "chat"
|
|
487
|
-
? SharedTaskCapabilities & {
|
|
488
|
-
: SharedTaskCapabilities & {
|
|
487
|
+
? SharedTaskCapabilities & { decline?: Lockable<true>; hold?: Lockable<true> }
|
|
488
|
+
: SharedTaskCapabilities & { decline?: Lockable<true> };
|
|
489
489
|
```
|
|
490
490
|
|
|
491
491
|
The channel arms are why `Task<"email">` rejects `hold` at compile time rather than at runtime.
|
|
@@ -671,15 +671,15 @@ const TASK_COMMAND_NAMES = {
|
|
|
671
671
|
"hold",
|
|
672
672
|
"resume",
|
|
673
673
|
"disconnect",
|
|
674
|
-
"
|
|
674
|
+
"connect-back",
|
|
675
675
|
"transfer",
|
|
676
676
|
"lead-assist",
|
|
677
677
|
"conference",
|
|
678
678
|
"recording",
|
|
679
679
|
"complete",
|
|
680
680
|
],
|
|
681
|
-
chat: ["accept", "
|
|
682
|
-
email: ["accept", "
|
|
681
|
+
chat: ["accept", "decline", "pause", "resume", "complete"],
|
|
682
|
+
email: ["accept", "decline", "complete"],
|
|
683
683
|
} as const;
|
|
684
684
|
|
|
685
685
|
type TaskCommandName<C extends keyof typeof TASK_COMMAND_NAMES> =
|
|
@@ -695,7 +695,7 @@ type VoiceTaskCommand =
|
|
|
695
695
|
| { type: "hold" }
|
|
696
696
|
| { type: "resume" }
|
|
697
697
|
| { type: "disconnect" }
|
|
698
|
-
| { type: "
|
|
698
|
+
| { type: "connect-back"; dialId: DialId }
|
|
699
699
|
| { type: "transfer"; dialId: DialId; destination: string; action?: never }
|
|
700
700
|
| { type: "transfer"; action: "consult"; dialId: DialId; destination: string }
|
|
701
701
|
| { type: "transfer"; action: "complete" }
|
|
@@ -711,14 +711,14 @@ type VoiceTaskCommand =
|
|
|
711
711
|
|
|
712
712
|
type ChatTaskCommand =
|
|
713
713
|
| { type: "accept" }
|
|
714
|
-
| { type: "
|
|
714
|
+
| { type: "decline" }
|
|
715
715
|
| { type: "pause" }
|
|
716
716
|
| { type: "resume" }
|
|
717
717
|
| ({ type: "complete" } & DispositionPayload);
|
|
718
718
|
|
|
719
719
|
type EmailTaskCommand =
|
|
720
720
|
| { type: "accept" }
|
|
721
|
-
| { type: "
|
|
721
|
+
| { type: "decline" }
|
|
722
722
|
| ({ type: "complete" } & DispositionPayload);
|
|
723
723
|
|
|
724
724
|
type CustomTaskCommand = { type: "custom"; name: string; [key: string]: unknown };
|
|
@@ -741,7 +741,7 @@ type TaskCommandResult =
|
|
|
741
741
|
### Who decides what an agent may do
|
|
742
742
|
|
|
743
743
|
An agent desk has two managers, not one. **The queue** — a process, a work type — is owned by a
|
|
744
|
-
process manager and **allows** a set of capabilities: hold, mute,
|
|
744
|
+
process manager and **allows** a set of capabilities: hold, mute, connect back, new call, conference,
|
|
745
745
|
whether the number is visible, the actions it offers, the skills it needs. **The people** are
|
|
746
746
|
managed through the organisation's structure — a team, a location, the organisation itself, in
|
|
747
747
|
whatever combination the structure defines for a person — and **decide** per capability within
|
|
@@ -788,7 +788,7 @@ controls — is content, and is never locked.
|
|
|
788
788
|
**A lead sets the team's policy from their roster.** A login that declares
|
|
789
789
|
`capabilities.team.policyControl` may `executeTeamPolicy({ type: "set", capability, setting })`
|
|
790
790
|
with `on`, `off`, or `person`, for any task control, `dial`, or a skill — and only `hold`, `mute`
|
|
791
|
-
and skills may be `person`;
|
|
791
|
+
and skills may be `person`; connect back and new call are the team's, on or off, within what the queue
|
|
792
792
|
allows. The roster carries `policies` for such a login: every policy as it stands, who set it, and
|
|
793
793
|
`lockedBy` where a level above the team made it theirs to keep, which the lead sees and cannot
|
|
794
794
|
change — `executeTeamPolicy` on it answers `failed` with `omni.capability-not-enabled`.
|
|
@@ -2177,7 +2177,7 @@ The canonical task transitions are:
|
|
|
2177
2177
|
| `paused` | Provider or agent resumes the task | `in-progress` |
|
|
2178
2178
|
| `paused` | Agent cancels a consultation (`transfer` `cancel`) | `in-progress` |
|
|
2179
2179
|
| `in-progress` or `paused` | Contact handling ends and follow-up work remains | `completing` |
|
|
2180
|
-
| `completing` | Agent
|
|
2180
|
+
| `completing` | Agent connects back to the party (`connect-back`) | `in-progress` |
|
|
2181
2181
|
| Any phase | Provider emits `task-ended` | Removed |
|
|
2182
2182
|
|
|
2183
2183
|
Allocation, acceptance, and progress are distinct. Acceptance follows `autoAcceptTasks` and the
|
|
@@ -2188,7 +2188,7 @@ command.
|
|
|
2188
2188
|
**A task is never its audio.** A voice task is the allocation: the call is offered when it is
|
|
2189
2189
|
routed to the agent and accepted as its `acceptance` dictates, and its presence and phase follow
|
|
2190
2190
|
the provider's reports about the work — never the audio. Wherever audio moves — an offer, a hold, a
|
|
2191
|
-
consult, a conference leg joining or leaving, a transfer, a
|
|
2191
|
+
consult, a conference leg joining or leaving, a transfer, a connect-back — the media follows
|
|
2192
2192
|
separately, arriving on `task-media-started`, attaching through `openMedia` and ending with
|
|
2193
2193
|
`task-media-ended`. Omni does not ring,
|
|
2194
2194
|
bridge, or hold a line. How the phone rings, whether it rings at all, and where legs join and leave
|
|
@@ -2197,7 +2197,7 @@ phase it is in.
|
|
|
2197
2197
|
|
|
2198
2198
|
The line runs between the provider's word and Omni's own senses. `task-media-ended` is the
|
|
2199
2199
|
provider's report that primary handling ended — a fact about the work, which is why the completion
|
|
2200
|
-
allowance starts on it and the
|
|
2200
|
+
allowance starts on it and the Connect back control appears on it — and Omni follows that report as it
|
|
2201
2201
|
follows any other. What Omni never does is derive a task's state from its own media session: a
|
|
2202
2202
|
stream that drops, a track that ends, a transport that disconnects, a microphone that fails, an
|
|
2203
2203
|
endpoint re-registering change nothing about the task until the provider says so. Structurally:
|
|
@@ -2253,39 +2253,44 @@ and the agent takes as long as the work needs. Moving the task to `completing` l
|
|
|
2253
2253
|
deadline is not an alternative on a media channel: the clock starts at a real event, and delaying
|
|
2254
2254
|
that event would falsify the phase and everything timed from it.
|
|
2255
2255
|
|
|
2256
|
-
####
|
|
2256
|
+
#### Connecting back during completion
|
|
2257
2257
|
|
|
2258
|
-
A task that declares `
|
|
2259
|
-
`completing` -- to finish what the call left unfinished, on the same task rather than a new one
|
|
2260
|
-
|
|
2261
|
-
|
|
2258
|
+
A task that declares `connectBack` lets the agent connect back to the party while the task is
|
|
2259
|
+
`completing` -- to finish what the call left unfinished, on the same task rather than a new one,
|
|
2260
|
+
whoever placed the call in the first place. Most such calls came in, so this is not a redial: the
|
|
2261
|
+
agent rings a party who rang them. Omni issues `{ type: "connect-back", dialId }`; it is issuable
|
|
2262
|
+
only in `completing`, and only where the capability is declared. The provider knows who the party
|
|
2263
|
+
is; the command carries no destination, and it is a dial like any other, so it carries the host's
|
|
2264
|
+
`dialId`, is answered `dialling`, and ends in one `dial-outcome`.
|
|
2262
2265
|
|
|
2263
|
-
On `
|
|
2266
|
+
On `dialling` the provider is placing the call and the task returns to `in-progress`: the agent is
|
|
2264
2267
|
working again, and the wrap allowance is **discarded, not paused**. From there the call is
|
|
2265
2268
|
reported as any call is -- `paused`, `in-progress`, and when its media ends, `task-media-ended`
|
|
2266
|
-
again, which starts a fresh allowance from that instant. A party who does not answer is a
|
|
2267
|
-
whose media ended: the task returns to `completing` through the
|
|
2268
|
-
again from there. At no point is an agent dialling against a
|
|
2269
|
+
again, which starts a fresh allowance from that instant. A party who does not answer is a dial
|
|
2270
|
+
whose outcome says so and a call whose media ended: the task returns to `completing` through the
|
|
2271
|
+
same event and the clock starts again from there. At no point is an agent dialling against a
|
|
2272
|
+
deadline.
|
|
2269
2273
|
|
|
2270
2274
|
**The control exists only while there is a window to use it in.** Under `agent-command` the task
|
|
2271
2275
|
stays `completing` until the agent completes it, so the window is open for as long as they need.
|
|
2272
2276
|
Under `provider-automatic` the window is the allowance -- and with `wrapAllowance: 0` there
|
|
2273
|
-
is none: the provider disposes the task at provider end, and Omni does not offer
|
|
2274
|
-
the task declares. A capability names a control that can be used; on a task with no `completing`
|
|
2277
|
+
is none: the provider disposes the task at provider end, and Omni does not offer Connect back,
|
|
2278
|
+
whatever the task declares. A capability names a control that can be used; on a task with no `completing`
|
|
2275
2279
|
window it cannot, and declaring it there changes nothing.
|
|
2276
2280
|
|
|
2277
2281
|
```ts
|
|
2278
|
-
const
|
|
2282
|
+
const connectBackCapable = {
|
|
2279
2283
|
channel: "voice",
|
|
2280
|
-
capabilities: { hold: true,
|
|
2284
|
+
capabilities: { hold: true, connectBack: true, dispositions: true },
|
|
2281
2285
|
phase: "completing",
|
|
2282
2286
|
completionMode: "provider-automatic",
|
|
2283
2287
|
wrapAllowance: 30,
|
|
2284
2288
|
} satisfies Pick<Task<"voice">, "channel" | "capabilities" | "phase" | "completionMode" | "wrapAllowance">;
|
|
2285
2289
|
```
|
|
2286
2290
|
|
|
2287
|
-
With ten seconds of the thirty left, the agent presses
|
|
2288
|
-
"
|
|
2291
|
+
With ten seconds of the thirty left, the agent presses Connect back: `execute({ command: { type:
|
|
2292
|
+
"connect-back", dialId } })` returns `dialling`, the task is `in-progress`, and the thirty seconds
|
|
2293
|
+
are gone.
|
|
2289
2294
|
The second call ends: `task-media-ended`, the task is `completing`, and a new thirty seconds runs
|
|
2290
2295
|
from that instant.
|
|
2291
2296
|
|
|
@@ -2556,11 +2561,11 @@ const taskCapabilities = {
|
|
|
2556
2561
|
|
|
2557
2562
|
| Capability | Omni UI | Contract |
|
|
2558
2563
|
| --- | --- | --- |
|
|
2559
|
-
| `decline` | Pending-task button: Decline | The provider can decline a pending voice offer. Omni shows it only when provisioning also permits
|
|
2564
|
+
| `decline` | Pending-task button: Decline | The provider can decline a pending voice offer. Omni shows it only when provisioning also permits declining. |
|
|
2560
2565
|
| `mute` | Primary toggle: Mute | Omni may mute and unmute the agent's outbound audio. |
|
|
2561
2566
|
| `hold` | Primary toggle: Hold | Omni may issue voice-task `hold` and `resume` commands. |
|
|
2562
2567
|
| `agentDisconnect` | Primary button: Disconnect | Omni may disconnect real-time media without disposing the task. |
|
|
2563
|
-
| `
|
|
2568
|
+
| `connectBack` | Completing-task button: Connect back | Omni may have the provider connect the agent back to the task's party while the task is `completing`, returning it to `in-progress` on the same task. Not offered where there is no `completing` window: `provider-automatic` with a zero allowance disposes at provider end. See **Connecting back during completion**. |
|
|
2564
2569
|
| `blindTransfer` | Secondary menu item: Blind transfer | Omni may transfer the caller directly to a destination. |
|
|
2565
2570
|
| `consultTransfer` | Secondary menu item: Consult transfer | Omni may park the customer and call a destination first, then hand the customer over or cancel back. See **Consult transfer**. |
|
|
2566
2571
|
| `leadAssist` | Secondary menu item: Lead assist | Omni may ask a lead to join this call, with a note. The lead's decision reaches the agent on `Task.leadAssist`. See **Lead assist**. |
|
|
@@ -2674,7 +2679,7 @@ customer.
|
|
|
2674
2679
|
|
|
2675
2680
|
| Capability | Omni UI | Contract |
|
|
2676
2681
|
| --- | --- | --- |
|
|
2677
|
-
| `
|
|
2682
|
+
| `decline` | Pending-task button: Decline | The provider can decline a pending chat offer. Omni shows it only when provisioning also permits declining. |
|
|
2678
2683
|
| `hold` | Primary toggle: Hold | Omni may pause and resume agent handling of the chat. |
|
|
2679
2684
|
| `dispositions` | Primary button: Complete | Omni may request task disposal with a provider disposition and notes. |
|
|
2680
2685
|
|
|
@@ -2682,7 +2687,7 @@ customer.
|
|
|
2682
2687
|
|
|
2683
2688
|
| Capability | Omni UI | Contract |
|
|
2684
2689
|
| --- | --- | --- |
|
|
2685
|
-
| `
|
|
2690
|
+
| `decline` | Pending-task button: Decline | The provider can decline a pending email offer. Omni shows it only when provisioning also permits declining. |
|
|
2686
2691
|
| `dispositions` | Primary button: Complete | Omni may request task disposal with a provider disposition and notes. |
|
|
2687
2692
|
|
|
2688
2693
|
### Custom capabilities
|
|
@@ -2746,7 +2751,7 @@ inside Omni.
|
|
|
2746
2751
|
## Every dial has an outcome
|
|
2747
2752
|
|
|
2748
2753
|
Four commands place a call: `dial` from the idle dialpad, a blind or consult `transfer`, a
|
|
2749
|
-
`conference` `add`, and `
|
|
2754
|
+
`conference` `add`, and `connect-back`. Each is accepted or refused at once, and each then ends later
|
|
2750
2755
|
and apart from its answer -- the destination picks up, is busy, or never does -- and a dial placed
|
|
2751
2756
|
late in a call routinely outlives the call. Nothing in between is reported: the wire says
|
|
2752
2757
|
`dialling`, then says how it ended, once.
|
|
@@ -2806,7 +2811,7 @@ call it belonged to and never against the next one.
|
|
|
2806
2811
|
The stream knows a dial from three places: `TaskStream.dialled(dialId)`, which a host calls when it
|
|
2807
2812
|
places one; an entry on a task's `onCall`; and a step in its `handlingHistory`. Since a dialled entry
|
|
2808
2813
|
is listed from placement, `dialled()` is load-bearing only for a dial that never has an entry -- a
|
|
2809
|
-
blind transfer, a
|
|
2814
|
+
blind transfer, a connect-back, an idle dialpad call -- or whose entry has already left the room; an
|
|
2810
2815
|
outcome for a dial nobody placed and no task mentions is what `stream.dialOutcome.unknown` refuses.
|
|
2811
2816
|
|
|
2812
2817
|
**`answered` says what happened to the dial; `onCall` says who is in the room.** They are two
|
|
@@ -2824,7 +2829,7 @@ provider does report -- `busy`, `no-answer`, `unreachable`, `rejected` or `cance
|
|
|
2824
2829
|
(`manifest.dialOutcomes.unexplained.alone`): a provider that reports causes may honestly say the
|
|
2825
2830
|
switch gave none, while one that reports none would be sending the generic failure this set exists
|
|
2826
2831
|
to refuse. A provider that dials at all declares it: an idle
|
|
2827
|
-
dialpad requires it (`manifest.dialOutcomes.required`), and a task that declares `
|
|
2832
|
+
dialpad requires it (`manifest.dialOutcomes.required`), and a task that declares `connectBack`,
|
|
2828
2833
|
`blindTransfer`, `consultTransfer` or `conference` under a manifest without it is refused
|
|
2829
2834
|
(`task.capability.dialOutcomes.required`). Off voice nothing dials, and the field is a compile
|
|
2830
2835
|
error there.
|
|
@@ -3608,10 +3613,10 @@ declared:
|
|
|
3608
3613
|
| Command | What makes it available |
|
|
3609
3614
|
| --- | --- |
|
|
3610
3615
|
| `answer`, `accept` | Nothing. A task that was offered can be accepted, or offering it meant nothing. |
|
|
3611
|
-
| `decline
|
|
3616
|
+
| `decline` | The `decline` capability on any channel, **and** Omni provisioning permitting it. One word for refusing an offer, whatever the channel. |
|
|
3612
3617
|
| `start-call` | The `preparing` phase. It starts the contact a preview gave the agent time to read, so the phase is the gate and there is no capability. |
|
|
3613
3618
|
| `complete` | `completionMode: "agent-command"`. The `dispositions` capability decides whether a code travels with the command, never whether the command exists — a task Omni cannot complete never ends. |
|
|
3614
|
-
| `
|
|
3619
|
+
| `connect-back` | The `connectBack` capability **and** the `completing` phase. It exists to reach the party again after the call, so it has no meaning while the call is up. |
|
|
3615
3620
|
| `transfer` with `action: "consult"` | The `consultTransfer` capability. Blind `transfer` is gated by `blindTransfer`; the two are declared and offered separately. |
|
|
3616
3621
|
| `transfer` with `action: "complete"` or `"cancel"` | A consultation in progress -- a `consulted` entry on `Task.onCall`. Without one there is nothing to complete or cancel, and a provider that receives either answers `failed`. |
|
|
3617
3622
|
| `lead-assist` with `action: "request"` or `"cancel"` | The `leadAssist` capability. `cancel` needs a request standing -- `Task.leadAssist` with status `requested`. |
|