@absolutejs/voice 0.0.22-beta.50 → 0.0.22-beta.52
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/angular/index.d.ts +1 -0
- package/dist/angular/index.js +279 -37
- package/dist/angular/voice-ops-status.component.d.ts +15 -0
- package/dist/appKit.d.ts +9 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +108 -0
- package/dist/client/opsStatusWidget.d.ts +39 -0
- package/dist/index.js +34 -8
- package/dist/react/VoiceOpsStatus.d.ts +6 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +201 -1
- package/dist/svelte/createVoiceOpsStatus.d.ts +9 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +117 -0
- package/dist/vue/VoiceOpsStatus.d.ts +30 -0
- package/dist/vue/index.d.ts +1 -0
- package/dist/vue/index.js +175 -3
- package/package.json +1 -1
package/dist/angular/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { VoiceOpsStatusComponent } from './voice-ops-status.component';
|
|
1
2
|
export { VoiceAppKitStatusService } from './voice-app-kit-status.service';
|
|
2
3
|
export { VoiceStreamService } from './voice-stream.service';
|
|
3
4
|
export { VoiceControllerService } from './voice-controller.service';
|
package/dist/angular/index.js
CHANGED
|
@@ -69,8 +69,8 @@ var __decorateElement = (array, flags, name, decorators, target, extra) => {
|
|
|
69
69
|
return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
-
// src/angular/voice-
|
|
73
|
-
import {
|
|
72
|
+
// src/angular/voice-ops-status.component.ts
|
|
73
|
+
import { Component, Input, signal } from "@angular/core";
|
|
74
74
|
|
|
75
75
|
// src/client/appKitStatus.ts
|
|
76
76
|
var fetchVoiceAppKitStatus = async (path = "/app-kit/status", options = {}) => {
|
|
@@ -151,7 +151,248 @@ var createVoiceAppKitStatusStore = (path = "/app-kit/status", options = {}) => {
|
|
|
151
151
|
};
|
|
152
152
|
};
|
|
153
153
|
|
|
154
|
+
// src/client/opsStatusWidget.ts
|
|
155
|
+
var DEFAULT_TITLE = "Voice Ops Status";
|
|
156
|
+
var DEFAULT_DESCRIPTION = "Certified workflow, provider, and handoff readiness from the AbsoluteJS voice app kit.";
|
|
157
|
+
var SURFACE_LABELS = {
|
|
158
|
+
handoffs: "Handoffs",
|
|
159
|
+
providers: "Providers",
|
|
160
|
+
quality: "Quality",
|
|
161
|
+
sessions: "Sessions",
|
|
162
|
+
workflows: "Workflows"
|
|
163
|
+
};
|
|
164
|
+
var escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
165
|
+
var readNumber = (value, key) => value && typeof value === "object" && (key in value) ? Number(value[key] ?? 0) : 0;
|
|
166
|
+
var surfaceDetail = (surface) => {
|
|
167
|
+
const total = readNumber(surface, "total");
|
|
168
|
+
const failed = readNumber(surface, "failed");
|
|
169
|
+
const degraded = readNumber(surface, "degraded");
|
|
170
|
+
const source = surface && typeof surface === "object" && "source" in surface && typeof surface.source === "string" ? ` from ${surface.source}` : "";
|
|
171
|
+
if (degraded > 0) {
|
|
172
|
+
return `${degraded} degraded of ${total}`;
|
|
173
|
+
}
|
|
174
|
+
if (failed > 0) {
|
|
175
|
+
return `${failed} failing of ${total}${source}`;
|
|
176
|
+
}
|
|
177
|
+
return total > 0 ? `${total} passing${source}` : `No failures${source}`;
|
|
178
|
+
};
|
|
179
|
+
var getVoiceOpsStatusLabel = (report, error) => {
|
|
180
|
+
if (error) {
|
|
181
|
+
return "Unavailable";
|
|
182
|
+
}
|
|
183
|
+
if (!report) {
|
|
184
|
+
return "Checking";
|
|
185
|
+
}
|
|
186
|
+
return report.status === "pass" ? "Passing" : "Needs attention";
|
|
187
|
+
};
|
|
188
|
+
var createVoiceOpsStatusViewModel = (snapshot, options = {}) => {
|
|
189
|
+
const report = snapshot.report;
|
|
190
|
+
const surfaces = Object.entries(report?.surfaces ?? {}).map(([id, surface]) => {
|
|
191
|
+
const failed = readNumber(surface, "failed") || readNumber(surface, "degraded");
|
|
192
|
+
const total = readNumber(surface, "total");
|
|
193
|
+
const status = surface && typeof surface === "object" && "status" in surface ? surface.status ?? "pass" : "pass";
|
|
194
|
+
return {
|
|
195
|
+
detail: surfaceDetail(surface),
|
|
196
|
+
failed,
|
|
197
|
+
id,
|
|
198
|
+
label: SURFACE_LABELS[id] ?? id,
|
|
199
|
+
status,
|
|
200
|
+
total
|
|
201
|
+
};
|
|
202
|
+
});
|
|
203
|
+
return {
|
|
204
|
+
description: options.description ?? DEFAULT_DESCRIPTION,
|
|
205
|
+
error: snapshot.error,
|
|
206
|
+
isLoading: snapshot.isLoading,
|
|
207
|
+
label: getVoiceOpsStatusLabel(report, snapshot.error),
|
|
208
|
+
links: options.includeLinks === false ? [] : report?.links ?? [],
|
|
209
|
+
passed: report?.passed ?? 0,
|
|
210
|
+
status: snapshot.error ? "error" : report ? report.status : snapshot.isLoading ? "loading" : "loading",
|
|
211
|
+
surfaces,
|
|
212
|
+
title: options.title ?? DEFAULT_TITLE,
|
|
213
|
+
total: report?.total ?? 0,
|
|
214
|
+
updatedAt: snapshot.updatedAt
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
var renderVoiceOpsStatusHTML = (snapshot, options = {}) => {
|
|
218
|
+
const model = createVoiceOpsStatusViewModel(snapshot, options);
|
|
219
|
+
const surfaces = model.surfaces.length ? model.surfaces.map((surface) => `<li class="absolute-voice-ops-status__surface absolute-voice-ops-status__surface--${escapeHtml(surface.status)}">
|
|
220
|
+
<span>${escapeHtml(surface.label)}</span>
|
|
221
|
+
<strong>${escapeHtml(surface.detail)}</strong>
|
|
222
|
+
</li>`).join("") : '<li class="absolute-voice-ops-status__surface"><span>Status</span><strong>Waiting for first check</strong></li>';
|
|
223
|
+
const links = model.links.length ? `<nav class="absolute-voice-ops-status__links">${model.links.slice(0, 4).map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join("")}</nav>` : "";
|
|
224
|
+
return `<section class="absolute-voice-ops-status absolute-voice-ops-status--${escapeHtml(model.status)}">
|
|
225
|
+
<header class="absolute-voice-ops-status__header">
|
|
226
|
+
<span class="absolute-voice-ops-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
227
|
+
<strong class="absolute-voice-ops-status__label">${escapeHtml(model.label)}</strong>
|
|
228
|
+
</header>
|
|
229
|
+
<p class="absolute-voice-ops-status__description">${escapeHtml(model.description)}</p>
|
|
230
|
+
<div class="absolute-voice-ops-status__summary">
|
|
231
|
+
<span>${model.passed} passing</span>
|
|
232
|
+
<span>${Math.max(model.total - model.passed, 0)} failing</span>
|
|
233
|
+
<span>${model.total} checks</span>
|
|
234
|
+
</div>
|
|
235
|
+
<ul class="absolute-voice-ops-status__surfaces">${surfaces}</ul>
|
|
236
|
+
${model.error ? `<p class="absolute-voice-ops-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
237
|
+
${links}
|
|
238
|
+
</section>`;
|
|
239
|
+
};
|
|
240
|
+
var getVoiceOpsStatusCSS = () => `.absolute-voice-ops-status{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;box-shadow:0 18px 40px rgba(47,37,18,.12);font-family:inherit}.absolute-voice-ops-status--fail,.absolute-voice-ops-status--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-ops-status__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-ops-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-ops-status__label{font-size:28px;line-height:1}.absolute-voice-ops-status__description{color:#514733;margin:12px 0 0}.absolute-voice-ops-status__summary,.absolute-voice-ops-status__links{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-ops-status__summary span,.absolute-voice-ops-status__links a{border:1px solid #e6ddca;border-radius:999px;color:inherit;padding:6px 10px;text-decoration:none}.absolute-voice-ops-status__surfaces{display:grid;gap:8px;list-style:none;margin:16px 0 0;padding:0}.absolute-voice-ops-status__surface{align-items:center;background:#fff;border:1px solid #eee4d2;border-radius:14px;display:flex;gap:12px;justify-content:space-between;padding:10px 12px}.absolute-voice-ops-status__surface--fail{border-color:#f2a7a7}.absolute-voice-ops-status__surface span{color:#655944}.absolute-voice-ops-status__error{color:#9f1239;font-weight:700}`;
|
|
241
|
+
var mountVoiceOpsStatus = (element, path = "/app-kit/status", options = {}) => {
|
|
242
|
+
const store = createVoiceAppKitStatusStore(path, options);
|
|
243
|
+
const render = () => {
|
|
244
|
+
element.innerHTML = renderVoiceOpsStatusHTML(store.getSnapshot(), options);
|
|
245
|
+
};
|
|
246
|
+
const unsubscribe = store.subscribe(render);
|
|
247
|
+
render();
|
|
248
|
+
store.refresh().catch(() => {});
|
|
249
|
+
return {
|
|
250
|
+
close: () => {
|
|
251
|
+
unsubscribe();
|
|
252
|
+
store.close();
|
|
253
|
+
},
|
|
254
|
+
refresh: store.refresh
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// src/angular/voice-ops-status.component.ts
|
|
259
|
+
var _dec = [
|
|
260
|
+
Component({
|
|
261
|
+
selector: "absolute-voice-ops-status",
|
|
262
|
+
standalone: true,
|
|
263
|
+
template: `
|
|
264
|
+
<section
|
|
265
|
+
class="absolute-voice-ops-status"
|
|
266
|
+
[class.absolute-voice-ops-status--pass]="model().status === 'pass'"
|
|
267
|
+
[class.absolute-voice-ops-status--fail]="model().status === 'fail'"
|
|
268
|
+
[class.absolute-voice-ops-status--loading]="model().status === 'loading'"
|
|
269
|
+
[class.absolute-voice-ops-status--error]="model().status === 'error'"
|
|
270
|
+
>
|
|
271
|
+
<header class="absolute-voice-ops-status__header">
|
|
272
|
+
<span class="absolute-voice-ops-status__eyebrow">{{
|
|
273
|
+
model().title
|
|
274
|
+
}}</span>
|
|
275
|
+
<strong class="absolute-voice-ops-status__label">{{
|
|
276
|
+
model().label
|
|
277
|
+
}}</strong>
|
|
278
|
+
</header>
|
|
279
|
+
<p class="absolute-voice-ops-status__description">
|
|
280
|
+
{{ model().description }}
|
|
281
|
+
</p>
|
|
282
|
+
<div class="absolute-voice-ops-status__summary">
|
|
283
|
+
<span>{{ model().passed }} passing</span>
|
|
284
|
+
<span>{{ model().total - model().passed }} failing</span>
|
|
285
|
+
<span>{{ model().total }} checks</span>
|
|
286
|
+
</div>
|
|
287
|
+
<ul class="absolute-voice-ops-status__surfaces">
|
|
288
|
+
@if (model().surfaces.length > 0) {
|
|
289
|
+
@for (surface of model().surfaces; track surface.id) {
|
|
290
|
+
<li
|
|
291
|
+
class="absolute-voice-ops-status__surface"
|
|
292
|
+
[class.absolute-voice-ops-status__surface--pass]="
|
|
293
|
+
surface.status === 'pass'
|
|
294
|
+
"
|
|
295
|
+
[class.absolute-voice-ops-status__surface--fail]="
|
|
296
|
+
surface.status === 'fail'
|
|
297
|
+
"
|
|
298
|
+
>
|
|
299
|
+
<span>{{ surface.label }}</span>
|
|
300
|
+
<strong>{{ surface.detail }}</strong>
|
|
301
|
+
</li>
|
|
302
|
+
}
|
|
303
|
+
} @else {
|
|
304
|
+
<li class="absolute-voice-ops-status__surface">
|
|
305
|
+
<span>Status</span>
|
|
306
|
+
<strong>Waiting for first check</strong>
|
|
307
|
+
</li>
|
|
308
|
+
}
|
|
309
|
+
</ul>
|
|
310
|
+
@if (model().error) {
|
|
311
|
+
<p class="absolute-voice-ops-status__error">{{ model().error }}</p>
|
|
312
|
+
}
|
|
313
|
+
@if (model().links.length > 0) {
|
|
314
|
+
<nav class="absolute-voice-ops-status__links">
|
|
315
|
+
@for (link of model().links.slice(0, 4); track link.href) {
|
|
316
|
+
<a [href]="link.href">{{ link.label }}</a>
|
|
317
|
+
}
|
|
318
|
+
</nav>
|
|
319
|
+
}
|
|
320
|
+
</section>
|
|
321
|
+
`
|
|
322
|
+
})
|
|
323
|
+
];
|
|
324
|
+
var _dec2 = [
|
|
325
|
+
Input()
|
|
326
|
+
];
|
|
327
|
+
var _dec3 = [
|
|
328
|
+
Input()
|
|
329
|
+
];
|
|
330
|
+
var _dec4 = [
|
|
331
|
+
Input()
|
|
332
|
+
];
|
|
333
|
+
var _dec5 = [
|
|
334
|
+
Input()
|
|
335
|
+
];
|
|
336
|
+
var _dec6 = [
|
|
337
|
+
Input()
|
|
338
|
+
];
|
|
339
|
+
var _init = __decoratorStart(undefined);
|
|
340
|
+
|
|
341
|
+
class VoiceOpsStatusComponent {
|
|
342
|
+
constructor() {
|
|
343
|
+
this.description = __runInitializers(_init, 8, this);
|
|
344
|
+
__runInitializers(_init, 11, this);
|
|
345
|
+
this.includeLinks = __runInitializers(_init, 12, this, true);
|
|
346
|
+
__runInitializers(_init, 15, this);
|
|
347
|
+
this.intervalMs = __runInitializers(_init, 16, this);
|
|
348
|
+
__runInitializers(_init, 19, this);
|
|
349
|
+
this.path = __runInitializers(_init, 20, this, "/app-kit/status");
|
|
350
|
+
__runInitializers(_init, 23, this);
|
|
351
|
+
this.title = __runInitializers(_init, 24, this);
|
|
352
|
+
__runInitializers(_init, 27, this);
|
|
353
|
+
}
|
|
354
|
+
cleanup = () => {};
|
|
355
|
+
store;
|
|
356
|
+
model = signal(createVoiceOpsStatusViewModel({
|
|
357
|
+
error: null,
|
|
358
|
+
isLoading: true
|
|
359
|
+
}));
|
|
360
|
+
ngOnInit() {
|
|
361
|
+
const options = this.options();
|
|
362
|
+
this.store = createVoiceAppKitStatusStore(this.path, options);
|
|
363
|
+
const sync = () => {
|
|
364
|
+
this.model.set(createVoiceOpsStatusViewModel(this.store.getSnapshot(), options));
|
|
365
|
+
};
|
|
366
|
+
this.cleanup = this.store.subscribe(sync);
|
|
367
|
+
sync();
|
|
368
|
+
if (typeof window !== "undefined") {
|
|
369
|
+
this.store.refresh().catch(() => {});
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
ngOnDestroy() {
|
|
373
|
+
this.cleanup();
|
|
374
|
+
this.store?.close();
|
|
375
|
+
}
|
|
376
|
+
options() {
|
|
377
|
+
return {
|
|
378
|
+
description: this.description,
|
|
379
|
+
includeLinks: this.includeLinks,
|
|
380
|
+
intervalMs: this.intervalMs,
|
|
381
|
+
title: this.title
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
__decorateElement(_init, 5, "description", _dec2, VoiceOpsStatusComponent);
|
|
386
|
+
__decorateElement(_init, 5, "includeLinks", _dec3, VoiceOpsStatusComponent);
|
|
387
|
+
__decorateElement(_init, 5, "intervalMs", _dec4, VoiceOpsStatusComponent);
|
|
388
|
+
__decorateElement(_init, 5, "path", _dec5, VoiceOpsStatusComponent);
|
|
389
|
+
__decorateElement(_init, 5, "title", _dec6, VoiceOpsStatusComponent);
|
|
390
|
+
VoiceOpsStatusComponent = __decorateElement(_init, 0, "VoiceOpsStatusComponent", _dec, VoiceOpsStatusComponent);
|
|
391
|
+
__runInitializers(_init, 1, VoiceOpsStatusComponent);
|
|
392
|
+
__decoratorMetadata(_init, VoiceOpsStatusComponent);
|
|
393
|
+
let _VoiceOpsStatusComponent = VoiceOpsStatusComponent;
|
|
154
394
|
// src/angular/voice-app-kit-status.service.ts
|
|
395
|
+
import { computed, Injectable, signal as signal2 } from "@angular/core";
|
|
155
396
|
var _dec = [
|
|
156
397
|
Injectable({ providedIn: "root" })
|
|
157
398
|
];
|
|
@@ -160,10 +401,10 @@ var _init = __decoratorStart(undefined);
|
|
|
160
401
|
class VoiceAppKitStatusService {
|
|
161
402
|
connect(path = "/app-kit/status", options = {}) {
|
|
162
403
|
const store = createVoiceAppKitStatusStore(path, options);
|
|
163
|
-
const errorSignal =
|
|
164
|
-
const isLoadingSignal =
|
|
165
|
-
const reportSignal =
|
|
166
|
-
const updatedAtSignal =
|
|
404
|
+
const errorSignal = signal2(null);
|
|
405
|
+
const isLoadingSignal = signal2(false);
|
|
406
|
+
const reportSignal = signal2(undefined);
|
|
407
|
+
const updatedAtSignal = signal2(undefined);
|
|
167
408
|
const sync = () => {
|
|
168
409
|
const snapshot = store.getSnapshot();
|
|
169
410
|
errorSignal.set(snapshot.error);
|
|
@@ -194,7 +435,7 @@ __runInitializers(_init, 1, VoiceAppKitStatusService);
|
|
|
194
435
|
__decoratorMetadata(_init, VoiceAppKitStatusService);
|
|
195
436
|
let _VoiceAppKitStatusService = VoiceAppKitStatusService;
|
|
196
437
|
// src/angular/voice-stream.service.ts
|
|
197
|
-
import { computed as computed2, Injectable as Injectable2, signal as
|
|
438
|
+
import { computed as computed2, Injectable as Injectable2, signal as signal3 } from "@angular/core";
|
|
198
439
|
|
|
199
440
|
// src/client/actions.ts
|
|
200
441
|
var normalizeErrorMessage = (value) => {
|
|
@@ -718,15 +959,15 @@ var _init = __decoratorStart(undefined);
|
|
|
718
959
|
class VoiceStreamService {
|
|
719
960
|
connect(path, options = {}) {
|
|
720
961
|
const stream = createVoiceStream(path, options);
|
|
721
|
-
const assistantAudioSignal =
|
|
722
|
-
const assistantTextsSignal =
|
|
723
|
-
const callSignal =
|
|
724
|
-
const errorSignal =
|
|
725
|
-
const isConnectedSignal =
|
|
726
|
-
const partialSignal =
|
|
727
|
-
const sessionIdSignal =
|
|
728
|
-
const statusSignal =
|
|
729
|
-
const turnsSignal =
|
|
962
|
+
const assistantAudioSignal = signal3([]);
|
|
963
|
+
const assistantTextsSignal = signal3([]);
|
|
964
|
+
const callSignal = signal3(null);
|
|
965
|
+
const errorSignal = signal3(null);
|
|
966
|
+
const isConnectedSignal = signal3(false);
|
|
967
|
+
const partialSignal = signal3("");
|
|
968
|
+
const sessionIdSignal = signal3(stream.sessionId);
|
|
969
|
+
const statusSignal = signal3(stream.status);
|
|
970
|
+
const turnsSignal = signal3([]);
|
|
730
971
|
const sync = () => {
|
|
731
972
|
assistantAudioSignal.set([...stream.assistantAudio]);
|
|
732
973
|
assistantTextsSignal.set([...stream.assistantTexts]);
|
|
@@ -765,7 +1006,7 @@ __runInitializers(_init, 1, VoiceStreamService);
|
|
|
765
1006
|
__decoratorMetadata(_init, VoiceStreamService);
|
|
766
1007
|
let _VoiceStreamService = VoiceStreamService;
|
|
767
1008
|
// src/angular/voice-controller.service.ts
|
|
768
|
-
import { computed as computed3, Injectable as Injectable3, signal as
|
|
1009
|
+
import { computed as computed3, Injectable as Injectable3, signal as signal4 } from "@angular/core";
|
|
769
1010
|
|
|
770
1011
|
// src/client/htmx.ts
|
|
771
1012
|
var DEFAULT_EVENT_NAME = "voice-refresh";
|
|
@@ -1406,16 +1647,16 @@ var _init = __decoratorStart(undefined);
|
|
|
1406
1647
|
class VoiceControllerService {
|
|
1407
1648
|
connect(path, options = {}) {
|
|
1408
1649
|
const controller = createVoiceController(path, options);
|
|
1409
|
-
const assistantAudioSignal =
|
|
1410
|
-
const assistantTextsSignal =
|
|
1411
|
-
const errorSignal =
|
|
1412
|
-
const isConnectedSignal =
|
|
1413
|
-
const isRecordingSignal =
|
|
1414
|
-
const partialSignal =
|
|
1415
|
-
const recordingErrorSignal =
|
|
1416
|
-
const sessionIdSignal =
|
|
1417
|
-
const statusSignal =
|
|
1418
|
-
const turnsSignal =
|
|
1650
|
+
const assistantAudioSignal = signal4([]);
|
|
1651
|
+
const assistantTextsSignal = signal4([]);
|
|
1652
|
+
const errorSignal = signal4(null);
|
|
1653
|
+
const isConnectedSignal = signal4(false);
|
|
1654
|
+
const isRecordingSignal = signal4(false);
|
|
1655
|
+
const partialSignal = signal4("");
|
|
1656
|
+
const recordingErrorSignal = signal4(null);
|
|
1657
|
+
const sessionIdSignal = signal4(controller.sessionId);
|
|
1658
|
+
const statusSignal = signal4(controller.status);
|
|
1659
|
+
const turnsSignal = signal4([]);
|
|
1419
1660
|
const sync = () => {
|
|
1420
1661
|
assistantAudioSignal.set([...controller.assistantAudio]);
|
|
1421
1662
|
assistantTextsSignal.set([...controller.assistantTexts]);
|
|
@@ -1459,7 +1700,7 @@ __runInitializers(_init, 1, VoiceControllerService);
|
|
|
1459
1700
|
__decoratorMetadata(_init, VoiceControllerService);
|
|
1460
1701
|
let _VoiceControllerService = VoiceControllerService;
|
|
1461
1702
|
// src/angular/voice-provider-status.service.ts
|
|
1462
|
-
import { computed as computed4, Injectable as Injectable4, signal as
|
|
1703
|
+
import { computed as computed4, Injectable as Injectable4, signal as signal5 } from "@angular/core";
|
|
1463
1704
|
|
|
1464
1705
|
// src/client/providerStatus.ts
|
|
1465
1706
|
var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
|
|
@@ -1550,10 +1791,10 @@ var _init = __decoratorStart(undefined);
|
|
|
1550
1791
|
class VoiceProviderStatusService {
|
|
1551
1792
|
connect(path = "/api/provider-status", options = {}) {
|
|
1552
1793
|
const store = createVoiceProviderStatusStore(path, options);
|
|
1553
|
-
const errorSignal =
|
|
1554
|
-
const isLoadingSignal =
|
|
1555
|
-
const providersSignal =
|
|
1556
|
-
const updatedAtSignal =
|
|
1794
|
+
const errorSignal = signal5(null);
|
|
1795
|
+
const isLoadingSignal = signal5(false);
|
|
1796
|
+
const providersSignal = signal5([]);
|
|
1797
|
+
const updatedAtSignal = signal5(undefined);
|
|
1557
1798
|
const sync = () => {
|
|
1558
1799
|
const snapshot = store.getSnapshot();
|
|
1559
1800
|
errorSignal.set(snapshot.error);
|
|
@@ -1582,7 +1823,7 @@ __runInitializers(_init, 1, VoiceProviderStatusService);
|
|
|
1582
1823
|
__decoratorMetadata(_init, VoiceProviderStatusService);
|
|
1583
1824
|
let _VoiceProviderStatusService = VoiceProviderStatusService;
|
|
1584
1825
|
// src/angular/voice-workflow-status.service.ts
|
|
1585
|
-
import { computed as computed5, Injectable as Injectable5, signal as
|
|
1826
|
+
import { computed as computed5, Injectable as Injectable5, signal as signal6 } from "@angular/core";
|
|
1586
1827
|
|
|
1587
1828
|
// src/client/workflowStatus.ts
|
|
1588
1829
|
var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
|
|
@@ -1672,10 +1913,10 @@ var _init = __decoratorStart(undefined);
|
|
|
1672
1913
|
class VoiceWorkflowStatusService {
|
|
1673
1914
|
connect(path = "/evals/scenarios/json", options = {}) {
|
|
1674
1915
|
const store = createVoiceWorkflowStatusStore(path, options);
|
|
1675
|
-
const errorSignal =
|
|
1676
|
-
const isLoadingSignal =
|
|
1677
|
-
const reportSignal =
|
|
1678
|
-
const updatedAtSignal =
|
|
1916
|
+
const errorSignal = signal6(null);
|
|
1917
|
+
const isLoadingSignal = signal6(false);
|
|
1918
|
+
const reportSignal = signal6(undefined);
|
|
1919
|
+
const updatedAtSignal = signal6(undefined);
|
|
1679
1920
|
const sync = () => {
|
|
1680
1921
|
const snapshot = store.getSnapshot();
|
|
1681
1922
|
errorSignal.set(snapshot.error);
|
|
@@ -1709,6 +1950,7 @@ export {
|
|
|
1709
1950
|
VoiceWorkflowStatusService,
|
|
1710
1951
|
VoiceStreamService,
|
|
1711
1952
|
VoiceProviderStatusService,
|
|
1953
|
+
VoiceOpsStatusComponent,
|
|
1712
1954
|
VoiceControllerService,
|
|
1713
1955
|
VoiceAppKitStatusService
|
|
1714
1956
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { OnDestroy, OnInit } from '@angular/core';
|
|
2
|
+
import { type VoiceOpsStatusViewModel } from '../client/opsStatusWidget';
|
|
3
|
+
export declare class VoiceOpsStatusComponent implements OnDestroy, OnInit {
|
|
4
|
+
description?: string;
|
|
5
|
+
includeLinks: boolean;
|
|
6
|
+
intervalMs?: number;
|
|
7
|
+
path: string;
|
|
8
|
+
title?: string;
|
|
9
|
+
private cleanup;
|
|
10
|
+
private store?;
|
|
11
|
+
model: import("@angular/core").WritableSignal<VoiceOpsStatusViewModel>;
|
|
12
|
+
ngOnInit(): void;
|
|
13
|
+
ngOnDestroy(): void;
|
|
14
|
+
private options;
|
|
15
|
+
}
|
package/dist/appKit.d.ts
CHANGED
|
@@ -37,7 +37,15 @@ export type VoiceAppKitRoutesOptions<TProvider extends string = string> = {
|
|
|
37
37
|
};
|
|
38
38
|
export type VoiceAppKitStatus = 'pass' | 'fail';
|
|
39
39
|
export type VoiceAppKitStatusOptions = {
|
|
40
|
+
include?: {
|
|
41
|
+
handoffs?: boolean;
|
|
42
|
+
providers?: boolean;
|
|
43
|
+
quality?: boolean;
|
|
44
|
+
sessions?: boolean;
|
|
45
|
+
workflows?: boolean;
|
|
46
|
+
};
|
|
40
47
|
path?: string;
|
|
48
|
+
preferFixtureWorkflows?: boolean;
|
|
41
49
|
};
|
|
42
50
|
export type VoiceAppKitStatusReport = {
|
|
43
51
|
checkedAt: number;
|
|
@@ -66,6 +74,7 @@ export type VoiceAppKitStatusReport = {
|
|
|
66
74
|
};
|
|
67
75
|
workflows?: {
|
|
68
76
|
failed: number;
|
|
77
|
+
source: 'fixtures' | 'live';
|
|
69
78
|
status: VoiceAppKitStatus;
|
|
70
79
|
total: number;
|
|
71
80
|
};
|
package/dist/client/index.d.ts
CHANGED
|
@@ -6,8 +6,10 @@ export { bindVoiceBargeIn, createVoiceDuplexController } from './duplex';
|
|
|
6
6
|
export { bindVoiceHTMX } from './htmx';
|
|
7
7
|
export { createMicrophoneCapture } from './microphone';
|
|
8
8
|
export { createVoiceAppKitStatusStore, fetchVoiceAppKitStatus } from './appKitStatus';
|
|
9
|
+
export { createVoiceOpsStatusViewModel, getVoiceOpsStatusCSS, getVoiceOpsStatusLabel, mountVoiceOpsStatus, renderVoiceOpsStatusHTML } from './opsStatusWidget';
|
|
9
10
|
export { createVoiceProviderStatusStore, fetchVoiceProviderStatus } from './providerStatus';
|
|
10
11
|
export { createVoiceWorkflowStatusStore, fetchVoiceWorkflowStatus } from './workflowStatus';
|
|
11
12
|
export type { VoiceAppKitStatusClientOptions, VoiceAppKitStatusSnapshot } from './appKitStatus';
|
|
13
|
+
export type { VoiceOpsStatusSurfaceView, VoiceOpsStatusViewModel, VoiceOpsStatusWidgetOptions } from './opsStatusWidget';
|
|
12
14
|
export type { VoiceProviderStatusClientOptions, VoiceProviderStatusSnapshot } from './providerStatus';
|
|
13
15
|
export type { VoiceWorkflowStatusClientOptions, VoiceWorkflowStatusSnapshot } from './workflowStatus';
|
package/dist/client/index.js
CHANGED
|
@@ -1701,6 +1701,109 @@ var createVoiceAppKitStatusStore = (path = "/app-kit/status", options = {}) => {
|
|
|
1701
1701
|
}
|
|
1702
1702
|
};
|
|
1703
1703
|
};
|
|
1704
|
+
// src/client/opsStatusWidget.ts
|
|
1705
|
+
var DEFAULT_TITLE = "Voice Ops Status";
|
|
1706
|
+
var DEFAULT_DESCRIPTION = "Certified workflow, provider, and handoff readiness from the AbsoluteJS voice app kit.";
|
|
1707
|
+
var SURFACE_LABELS = {
|
|
1708
|
+
handoffs: "Handoffs",
|
|
1709
|
+
providers: "Providers",
|
|
1710
|
+
quality: "Quality",
|
|
1711
|
+
sessions: "Sessions",
|
|
1712
|
+
workflows: "Workflows"
|
|
1713
|
+
};
|
|
1714
|
+
var escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1715
|
+
var readNumber = (value, key) => value && typeof value === "object" && (key in value) ? Number(value[key] ?? 0) : 0;
|
|
1716
|
+
var surfaceDetail = (surface) => {
|
|
1717
|
+
const total = readNumber(surface, "total");
|
|
1718
|
+
const failed = readNumber(surface, "failed");
|
|
1719
|
+
const degraded = readNumber(surface, "degraded");
|
|
1720
|
+
const source = surface && typeof surface === "object" && "source" in surface && typeof surface.source === "string" ? ` from ${surface.source}` : "";
|
|
1721
|
+
if (degraded > 0) {
|
|
1722
|
+
return `${degraded} degraded of ${total}`;
|
|
1723
|
+
}
|
|
1724
|
+
if (failed > 0) {
|
|
1725
|
+
return `${failed} failing of ${total}${source}`;
|
|
1726
|
+
}
|
|
1727
|
+
return total > 0 ? `${total} passing${source}` : `No failures${source}`;
|
|
1728
|
+
};
|
|
1729
|
+
var getVoiceOpsStatusLabel = (report, error) => {
|
|
1730
|
+
if (error) {
|
|
1731
|
+
return "Unavailable";
|
|
1732
|
+
}
|
|
1733
|
+
if (!report) {
|
|
1734
|
+
return "Checking";
|
|
1735
|
+
}
|
|
1736
|
+
return report.status === "pass" ? "Passing" : "Needs attention";
|
|
1737
|
+
};
|
|
1738
|
+
var createVoiceOpsStatusViewModel = (snapshot, options = {}) => {
|
|
1739
|
+
const report = snapshot.report;
|
|
1740
|
+
const surfaces = Object.entries(report?.surfaces ?? {}).map(([id, surface]) => {
|
|
1741
|
+
const failed = readNumber(surface, "failed") || readNumber(surface, "degraded");
|
|
1742
|
+
const total = readNumber(surface, "total");
|
|
1743
|
+
const status = surface && typeof surface === "object" && "status" in surface ? surface.status ?? "pass" : "pass";
|
|
1744
|
+
return {
|
|
1745
|
+
detail: surfaceDetail(surface),
|
|
1746
|
+
failed,
|
|
1747
|
+
id,
|
|
1748
|
+
label: SURFACE_LABELS[id] ?? id,
|
|
1749
|
+
status,
|
|
1750
|
+
total
|
|
1751
|
+
};
|
|
1752
|
+
});
|
|
1753
|
+
return {
|
|
1754
|
+
description: options.description ?? DEFAULT_DESCRIPTION,
|
|
1755
|
+
error: snapshot.error,
|
|
1756
|
+
isLoading: snapshot.isLoading,
|
|
1757
|
+
label: getVoiceOpsStatusLabel(report, snapshot.error),
|
|
1758
|
+
links: options.includeLinks === false ? [] : report?.links ?? [],
|
|
1759
|
+
passed: report?.passed ?? 0,
|
|
1760
|
+
status: snapshot.error ? "error" : report ? report.status : snapshot.isLoading ? "loading" : "loading",
|
|
1761
|
+
surfaces,
|
|
1762
|
+
title: options.title ?? DEFAULT_TITLE,
|
|
1763
|
+
total: report?.total ?? 0,
|
|
1764
|
+
updatedAt: snapshot.updatedAt
|
|
1765
|
+
};
|
|
1766
|
+
};
|
|
1767
|
+
var renderVoiceOpsStatusHTML = (snapshot, options = {}) => {
|
|
1768
|
+
const model = createVoiceOpsStatusViewModel(snapshot, options);
|
|
1769
|
+
const surfaces = model.surfaces.length ? model.surfaces.map((surface) => `<li class="absolute-voice-ops-status__surface absolute-voice-ops-status__surface--${escapeHtml(surface.status)}">
|
|
1770
|
+
<span>${escapeHtml(surface.label)}</span>
|
|
1771
|
+
<strong>${escapeHtml(surface.detail)}</strong>
|
|
1772
|
+
</li>`).join("") : '<li class="absolute-voice-ops-status__surface"><span>Status</span><strong>Waiting for first check</strong></li>';
|
|
1773
|
+
const links = model.links.length ? `<nav class="absolute-voice-ops-status__links">${model.links.slice(0, 4).map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join("")}</nav>` : "";
|
|
1774
|
+
return `<section class="absolute-voice-ops-status absolute-voice-ops-status--${escapeHtml(model.status)}">
|
|
1775
|
+
<header class="absolute-voice-ops-status__header">
|
|
1776
|
+
<span class="absolute-voice-ops-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
1777
|
+
<strong class="absolute-voice-ops-status__label">${escapeHtml(model.label)}</strong>
|
|
1778
|
+
</header>
|
|
1779
|
+
<p class="absolute-voice-ops-status__description">${escapeHtml(model.description)}</p>
|
|
1780
|
+
<div class="absolute-voice-ops-status__summary">
|
|
1781
|
+
<span>${model.passed} passing</span>
|
|
1782
|
+
<span>${Math.max(model.total - model.passed, 0)} failing</span>
|
|
1783
|
+
<span>${model.total} checks</span>
|
|
1784
|
+
</div>
|
|
1785
|
+
<ul class="absolute-voice-ops-status__surfaces">${surfaces}</ul>
|
|
1786
|
+
${model.error ? `<p class="absolute-voice-ops-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
1787
|
+
${links}
|
|
1788
|
+
</section>`;
|
|
1789
|
+
};
|
|
1790
|
+
var getVoiceOpsStatusCSS = () => `.absolute-voice-ops-status{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;box-shadow:0 18px 40px rgba(47,37,18,.12);font-family:inherit}.absolute-voice-ops-status--fail,.absolute-voice-ops-status--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-ops-status__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-ops-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-ops-status__label{font-size:28px;line-height:1}.absolute-voice-ops-status__description{color:#514733;margin:12px 0 0}.absolute-voice-ops-status__summary,.absolute-voice-ops-status__links{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-ops-status__summary span,.absolute-voice-ops-status__links a{border:1px solid #e6ddca;border-radius:999px;color:inherit;padding:6px 10px;text-decoration:none}.absolute-voice-ops-status__surfaces{display:grid;gap:8px;list-style:none;margin:16px 0 0;padding:0}.absolute-voice-ops-status__surface{align-items:center;background:#fff;border:1px solid #eee4d2;border-radius:14px;display:flex;gap:12px;justify-content:space-between;padding:10px 12px}.absolute-voice-ops-status__surface--fail{border-color:#f2a7a7}.absolute-voice-ops-status__surface span{color:#655944}.absolute-voice-ops-status__error{color:#9f1239;font-weight:700}`;
|
|
1791
|
+
var mountVoiceOpsStatus = (element, path = "/app-kit/status", options = {}) => {
|
|
1792
|
+
const store = createVoiceAppKitStatusStore(path, options);
|
|
1793
|
+
const render = () => {
|
|
1794
|
+
element.innerHTML = renderVoiceOpsStatusHTML(store.getSnapshot(), options);
|
|
1795
|
+
};
|
|
1796
|
+
const unsubscribe = store.subscribe(render);
|
|
1797
|
+
render();
|
|
1798
|
+
store.refresh().catch(() => {});
|
|
1799
|
+
return {
|
|
1800
|
+
close: () => {
|
|
1801
|
+
unsubscribe();
|
|
1802
|
+
store.close();
|
|
1803
|
+
},
|
|
1804
|
+
refresh: store.refresh
|
|
1805
|
+
};
|
|
1806
|
+
};
|
|
1704
1807
|
// src/client/providerStatus.ts
|
|
1705
1808
|
var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
|
|
1706
1809
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
@@ -1859,6 +1962,10 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
|
|
|
1859
1962
|
};
|
|
1860
1963
|
};
|
|
1861
1964
|
export {
|
|
1965
|
+
renderVoiceOpsStatusHTML,
|
|
1966
|
+
mountVoiceOpsStatus,
|
|
1967
|
+
getVoiceOpsStatusLabel,
|
|
1968
|
+
getVoiceOpsStatusCSS,
|
|
1862
1969
|
fetchVoiceWorkflowStatus,
|
|
1863
1970
|
fetchVoiceProviderStatus,
|
|
1864
1971
|
fetchVoiceAppKitStatus,
|
|
@@ -1866,6 +1973,7 @@ export {
|
|
|
1866
1973
|
createVoiceWorkflowStatusStore,
|
|
1867
1974
|
createVoiceStream,
|
|
1868
1975
|
createVoiceProviderStatusStore,
|
|
1976
|
+
createVoiceOpsStatusViewModel,
|
|
1869
1977
|
createVoiceDuplexController,
|
|
1870
1978
|
createVoiceController,
|
|
1871
1979
|
createVoiceConnection,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { VoiceAppKitStatusReport } from '../appKit';
|
|
2
|
+
import { type VoiceAppKitStatusClientOptions, type VoiceAppKitStatusSnapshot } from './appKitStatus';
|
|
3
|
+
export type VoiceOpsStatusSurfaceView = {
|
|
4
|
+
detail: string;
|
|
5
|
+
failed: number;
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
status: 'pass' | 'fail';
|
|
9
|
+
total: number;
|
|
10
|
+
};
|
|
11
|
+
export type VoiceOpsStatusViewModel = {
|
|
12
|
+
description: string;
|
|
13
|
+
error: string | null;
|
|
14
|
+
isLoading: boolean;
|
|
15
|
+
label: string;
|
|
16
|
+
links: Array<{
|
|
17
|
+
href: string;
|
|
18
|
+
label: string;
|
|
19
|
+
}>;
|
|
20
|
+
passed: number;
|
|
21
|
+
status: 'pass' | 'fail' | 'loading' | 'error';
|
|
22
|
+
surfaces: VoiceOpsStatusSurfaceView[];
|
|
23
|
+
title: string;
|
|
24
|
+
total: number;
|
|
25
|
+
updatedAt?: number;
|
|
26
|
+
};
|
|
27
|
+
export type VoiceOpsStatusWidgetOptions = VoiceAppKitStatusClientOptions & {
|
|
28
|
+
description?: string;
|
|
29
|
+
includeLinks?: boolean;
|
|
30
|
+
title?: string;
|
|
31
|
+
};
|
|
32
|
+
export declare const getVoiceOpsStatusLabel: (report?: VoiceAppKitStatusReport | null, error?: string | null) => "Unavailable" | "Checking" | "Passing" | "Needs attention";
|
|
33
|
+
export declare const createVoiceOpsStatusViewModel: (snapshot: VoiceAppKitStatusSnapshot, options?: VoiceOpsStatusWidgetOptions) => VoiceOpsStatusViewModel;
|
|
34
|
+
export declare const renderVoiceOpsStatusHTML: (snapshot: VoiceAppKitStatusSnapshot, options?: VoiceOpsStatusWidgetOptions) => string;
|
|
35
|
+
export declare const getVoiceOpsStatusCSS: () => string;
|
|
36
|
+
export declare const mountVoiceOpsStatus: (element: Element, path?: string, options?: VoiceOpsStatusWidgetOptions) => {
|
|
37
|
+
close: () => void;
|
|
38
|
+
refresh: () => Promise<VoiceAppKitStatusReport | undefined>;
|
|
39
|
+
};
|