@xema/omni-protocol 0.1.38 → 0.1.39

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 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
- /** Reach the party again while `completing`; the task returns to `in-progress`. */
441
- callback?: Lockable<true>;
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>;
@@ -730,7 +730,7 @@ 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", "callback", "transfer", "lead-assist", "conference", "recording", "complete"];
733
+ readonly voice: readonly ["answer", "decline", "start-call", "mute", "hold", "resume", "disconnect", "connect-back", "transfer", "lead-assist", "conference", "recording", "complete"];
734
734
  readonly chat: readonly ["accept", "reject", "pause", "resume", "complete"];
735
735
  readonly email: readonly ["accept", "reject", "complete"];
736
736
  };
@@ -755,9 +755,9 @@ export type VoiceTaskCommand = {
755
755
  } | {
756
756
  type: "disconnect";
757
757
  }
758
- /** Issuable only in `completing`, under the `callback` capability. Dials the party's own number, so it names none. */
758
+ /** Issuable only in `completing`, under the `connectBack` capability. Dials the party's own number, so it names none. */
759
759
  | {
760
- type: "callback";
760
+ type: "connect-back";
761
761
  dialId: DialId;
762
762
  }
763
763
  /** Blind: hand the customer to `destination` with nobody consulted. Gated by `blindTransfer`. */
@@ -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. Callback and new call are never the person's; they are the
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
- "callback", "transfer", "lead-assist", "conference", "recording", "complete"],
74
+ "connect-back", "transfer", "lead-assist", "conference", "recording", "complete"],
75
75
  chat: ["accept", "reject", "pause", "resume", "complete"],
76
76
  email: ["accept", "reject", "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 === "callback")
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;
@@ -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 = ["callback", "blindTransfer", "consultTransfer", "conference"];
76
+ const DIALLING_CAPABILITIES = ["connectBack", "blindTransfer", "consultTransfer", "conference"];
77
77
  const SNAPSHOT_REASONS = membersOf({
78
78
  reconnected: true, "provider-requested": true,
79
79
  });
@@ -94,7 +94,7 @@ 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, callback: true, blindTransfer: true, consultTransfer: true, leadAssist: true, conference: true, recording: true,
97
+ agentDisconnect: true, connectBack: true, blindTransfer: true, consultTransfer: true, leadAssist: true, conference: true, recording: true,
98
98
  }),
99
99
  chat: membersOf({ browsers: true, dispositions: true, custom: true, reject: true, hold: true }),
100
100
  email: membersOf({ browsers: true, dispositions: true, custom: true, reject: 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 callback. Identified by the host's `dialId`, accepted as `dialling`, and ended by exactly one `dial-outcome`. See **Every dial has an outcome**. |
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
- callback?: Lockable<true>;
479
+ connectBack?: Lockable<true>;
480
480
  blindTransfer?: Lockable<true | DestinationDirectory>;
481
481
  consultTransfer?: Lockable<true | DestinationDirectory>;
482
482
  leadAssist?: Lockable<true>;
@@ -671,7 +671,7 @@ const TASK_COMMAND_NAMES = {
671
671
  "hold",
672
672
  "resume",
673
673
  "disconnect",
674
- "callback",
674
+ "connect-back",
675
675
  "transfer",
676
676
  "lead-assist",
677
677
  "conference",
@@ -695,7 +695,7 @@ type VoiceTaskCommand =
695
695
  | { type: "hold" }
696
696
  | { type: "resume" }
697
697
  | { type: "disconnect" }
698
- | { type: "callback"; dialId: DialId }
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" }
@@ -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, callback, new call, conference,
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`; callback and new call are the team's, on or off, within what the queue
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 calls the party back (`callback`) | `in-progress` |
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 callback — the media follows
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 callback control appears on it — and Omni follows that report as it
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
- #### Calling back during completion
2256
+ #### Connecting back during completion
2257
2257
 
2258
- A task that declares `callback` lets the agent reach the party again while the task is
2259
- `completing` -- to finish what the call left unfinished, on the same task rather than a new one.
2260
- Omni issues `{ type: "callback" }`; it is issuable only in `completing`, and only where the
2261
- capability is declared. The provider knows who the party is; the command carries no destination.
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 `applied` the provider is placing the call and the task returns to `in-progress`: the agent is
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 call
2267
- whose media ended: the task returns to `completing` through the same event and the clock starts
2268
- again from there. At no point is an agent dialling against a deadline.
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 Call back, whatever
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 callbackCapable = {
2282
+ const connectBackCapable = {
2279
2283
  channel: "voice",
2280
- capabilities: { hold: true, callback: true, dispositions: 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 Call back: `execute({ command: { type:
2288
- "callback" } })` returns `applied`, the task is `in-progress`, and the thirty seconds are gone.
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
 
@@ -2560,7 +2565,7 @@ const taskCapabilities = {
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
- | `callback` | Completing-task button: Call back | Omni may have the provider call the task's party back 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 **Calling back during completion**. |
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**. |
@@ -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 `callback`. Each is accepted or refused at once, and each then ends later
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 callback, an idle dialpad call -- or whose entry has already left the room; an
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 `callback`,
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.
@@ -3611,7 +3616,7 @@ declared:
3611
3616
  | `decline`, `reject` | The channel's decline or reject capability, **and** Omni provisioning permitting rejection. |
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
- | `callback` | The `callback` 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. |
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`. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xema/omni-protocol",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "The Omni protocol: the contract every provider adapter implements",
5
5
  "type": "module",
6
6
  "license": "MIT",