@xema/omni-protocol 0.1.41 → 0.1.42
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 +9 -1
- package/dist/index.js +6 -0
- package/dist/validation.js +23 -3
- package/guide.md +14 -5
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -638,7 +638,9 @@ export interface TaskAssisting {
|
|
|
638
638
|
/**
|
|
639
639
|
* On the lead's own task while they listen to a member's call: whose call, which call, and how the
|
|
640
640
|
* lead is heard, restated on every change of mode. Nothing of it reaches the member's task. There
|
|
641
|
-
* is no take-over here; a lead who wants the call uses lead assist.
|
|
641
|
+
* is no take-over here; a lead who wants the call uses lead assist. It is the lead's only task:
|
|
642
|
+
* a lead listens while holding no work of their own, idle or on a break of a kind in
|
|
643
|
+
* `MONITORING_BREAK_KINDS`.
|
|
642
644
|
*/
|
|
643
645
|
export interface TaskMonitoring {
|
|
644
646
|
memberId: UserId;
|
|
@@ -927,6 +929,12 @@ export declare const BREAK_KINDS: readonly ["short-break", "meal", "rest", "trai
|
|
|
927
929
|
* problem one level up. `other` matches nothing, including another provider's `other`.
|
|
928
930
|
*/
|
|
929
931
|
export type BreakKind = (typeof BREAK_KINDS)[number];
|
|
932
|
+
/**
|
|
933
|
+
* The breaks during which a lead may listen to a member's call: work of another sort, not rest.
|
|
934
|
+
* A monitoring task is the one task a break in effect may hold, and only on one of these.
|
|
935
|
+
*/
|
|
936
|
+
export declare const MONITORING_BREAK_KINDS: readonly ["coaching", "administrative", "training"];
|
|
937
|
+
export declare const breakKindAllowsMonitoring: (kind: BreakKind | undefined) => boolean;
|
|
930
938
|
export interface BreakReason {
|
|
931
939
|
id: string;
|
|
932
940
|
label: string;
|
package/dist/index.js
CHANGED
|
@@ -90,6 +90,12 @@ export const BREAK_KINDS = [
|
|
|
90
90
|
"short-break", "meal", "rest", "training", "coaching",
|
|
91
91
|
"meeting", "administrative", "technical", "personal", "other",
|
|
92
92
|
];
|
|
93
|
+
/**
|
|
94
|
+
* The breaks during which a lead may listen to a member's call: work of another sort, not rest.
|
|
95
|
+
* A monitoring task is the one task a break in effect may hold, and only on one of these.
|
|
96
|
+
*/
|
|
97
|
+
export const MONITORING_BREAK_KINDS = ["coaching", "administrative", "training"];
|
|
98
|
+
export const breakKindAllowsMonitoring = (kind) => kind !== undefined && MONITORING_BREAK_KINDS.includes(kind);
|
|
93
99
|
export const OMNI_FAILURE_CODES = [
|
|
94
100
|
"omni.not-authenticated",
|
|
95
101
|
"omni.capability-not-enabled",
|
package/dist/validation.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// Each list is pinned to its type both ways -- a member the type lacks, or a member the list
|
|
10
10
|
// lacks, fails to compile -- so what the validators accept cannot drift from what the
|
|
11
11
|
// declarations say.
|
|
12
|
-
import { ALLOWED_BROWSER_URL_SCHEMES, BREAK_KINDS, BROWSER_ISOLATION_SCHEMES, HANDLING_STEPS_THAT_DIAL, IDLE_CAPABILITIES, OMNI_FAILURE_CODES, OMNI_SUPPORTED_PROTOCOL_VERSIONS, negotiateProtocolVersion, DEFAULT_LEVELS, effectiveLevels, } from "./index.js";
|
|
12
|
+
import { ALLOWED_BROWSER_URL_SCHEMES, BREAK_KINDS, MONITORING_BREAK_KINDS, BROWSER_ISOLATION_SCHEMES, HANDLING_STEPS_THAT_DIAL, IDLE_CAPABILITIES, OMNI_FAILURE_CODES, OMNI_SUPPORTED_PROTOCOL_VERSIONS, negotiateProtocolVersion, DEFAULT_LEVELS, effectiveLevels, } from "./index.js";
|
|
13
13
|
export class ProtocolConformanceError extends Error {
|
|
14
14
|
violations;
|
|
15
15
|
constructor(violations, summary = "Adapter violates the Omni protocol") {
|
|
@@ -1188,11 +1188,31 @@ export function validateSnapshot(snapshot, manifest, path = "snapshot", context
|
|
|
1188
1188
|
}
|
|
1189
1189
|
});
|
|
1190
1190
|
}
|
|
1191
|
+
// A lead listens while holding no work of their own: a monitoring task is the only task.
|
|
1192
|
+
if (Array.isArray(snapshot.tasks) && snapshot.tasks.length > 1) {
|
|
1193
|
+
snapshot.tasks.forEach((task, index) => {
|
|
1194
|
+
if (isPlainObject(task) && task.monitoring !== undefined) {
|
|
1195
|
+
into.add("snapshot.monitoring.alone", `${path}.tasks[${index}].monitoring`, "a lead listens only while holding no task of their own");
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1191
1199
|
// A break in effect begins when the work ends, so it holds no task. A snapshot reporting both
|
|
1192
|
-
// describes a state the agent cannot be in, whichever half is stale.
|
|
1200
|
+
// describes a state the agent cannot be in, whichever half is stale. The one exception is a
|
|
1201
|
+
// lead listening to a call during a break that is work of another sort -- coaching,
|
|
1202
|
+
// administrative, training -- and on no other.
|
|
1193
1203
|
if (isPlainObject(snapshot.break) && snapshot.break.approval === "in-effect"
|
|
1194
1204
|
&& Array.isArray(snapshot.tasks) && snapshot.tasks.length > 0) {
|
|
1195
|
-
|
|
1205
|
+
const listening = snapshot.tasks.every((task) => isPlainObject(task) && task.monitoring !== undefined);
|
|
1206
|
+
if (!listening) {
|
|
1207
|
+
into.add("break.in-effect.tasks", `${path}.tasks`, "a break in effect holds no task: it begins when the work ends, and until then the state is starting-after-task");
|
|
1208
|
+
}
|
|
1209
|
+
else {
|
|
1210
|
+
const state = snapshot.break;
|
|
1211
|
+
const reasons = Array.isArray(state.reasons) ? state.reasons : [];
|
|
1212
|
+
const active = reasons.find((reason) => isPlainObject(reason) && reason.id === state.activeReasonId);
|
|
1213
|
+
const kind = isPlainObject(active) ? active.kind : undefined;
|
|
1214
|
+
into.require(typeof kind === "string" && MONITORING_BREAK_KINDS.includes(kind), "snapshot.monitoring.break", `${path}.tasks`, `a lead listens during a ${MONITORING_BREAK_KINDS.join(", ")} break and no other; the active reason is ${kind === undefined ? "unstated" : String(kind)}`);
|
|
1215
|
+
}
|
|
1196
1216
|
}
|
|
1197
1217
|
// Presence is the permission, and it cuts both ways: data a provider never declared a
|
|
1198
1218
|
// capability for is data Omni would show against a control the agent does not have.
|
package/guide.md
CHANGED
|
@@ -2933,7 +2933,7 @@ rendering one as the other tells an agent to wait for somebody who is never comi
|
|
|
2933
2933
|
| `awaiting-decision` | A person has to decide. The agent is waiting on somebody. |
|
|
2934
2934
|
| `granted` | A person decided yes. Omni may now tell this provider to stop the agent; until it does, work continues normally, and this says nothing about why Omni has not. |
|
|
2935
2935
|
| `starting-after-task` | Omni has told the provider to stop; the break begins when the current task ends. No new work arrives meanwhile, and nobody needs to act. |
|
|
2936
|
-
| `in-effect` | The agent is on the break now. It holds no task: a break begins when the work ends, so a snapshot reporting `in-effect` beside a task is refused as `break.in-effect.tasks`. |
|
|
2936
|
+
| `in-effect` | The agent is on the break now. It holds no task: a break begins when the work ends, so a snapshot reporting `in-effect` beside a task is refused as `break.in-effect.tasks`. The one exception is a lead's monitoring task during a `coaching`, `administrative` or `training` break -- see **Monitoring a call**. |
|
|
2937
2937
|
|
|
2938
2938
|
A denial is a decision, not a standing approval state. The provider transitions the request directly
|
|
2939
2939
|
to `not-requested`; Omni returns the agent to idle and never asks again on their behalf. They saw the
|
|
@@ -3465,10 +3465,19 @@ executeTeamMonitor({ command: { type: "leave" } })
|
|
|
3465
3465
|
provider bridges the lead's leg into the member's call in the mode stated. `monitoring.mode` is
|
|
3466
3466
|
the state, restated on every change, and a `whisper` or `barge` the login's list does not include
|
|
3467
3467
|
is answered `failed`. **A lead listens to one call at a time** (`snapshot.monitoring.single`), and
|
|
3468
|
-
a task is a joined call or a monitored one, never both (`task.monitoring.assisting`).
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3468
|
+
a task is a joined call or a monitored one, never both (`task.monitoring.assisting`). The member's
|
|
3469
|
+
call ending ends the lead's task as it ends the member's, with `left`, since the lead was never
|
|
3470
|
+
handling it.
|
|
3471
|
+
|
|
3472
|
+
**A lead listens only while holding no work of their own.** A monitoring task is the lead's only
|
|
3473
|
+
task, and a snapshot carrying one beside any other is refused (`snapshot.monitoring.alone`); Omni
|
|
3474
|
+
offers Monitor to a lead with no task. That includes a lead on a break -- unlike joining, which a
|
|
3475
|
+
break forbids -- but only a break that is work of another sort: `coaching`, `administrative` or
|
|
3476
|
+
`training`, the kinds in `MONITORING_BREAK_KINDS`, and never a meal or a rest. A break in effect
|
|
3477
|
+
otherwise holds no task; the monitoring task is its one exception, and a snapshot carrying one
|
|
3478
|
+
during a break whose active reason is of any other kind, or of no stated kind, is refused
|
|
3479
|
+
(`snapshot.monitoring.break`). The kind decides, not the reason's name: a centre that wants leads
|
|
3480
|
+
listening during a break declares that break `coaching`, `administrative` or `training`.
|
|
3472
3481
|
|
|
3473
3482
|
**Nothing reaches the member.** The member's task carries no trace of a monitoring lead in any
|
|
3474
3483
|
mode: not on `onCall`, not in the record. Whether a whisper is announced to the agent is the
|