@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/index.js
CHANGED
|
@@ -9198,24 +9198,49 @@ var countStatus = (statuses) => ({
|
|
|
9198
9198
|
});
|
|
9199
9199
|
var summarizeVoiceAppKitStatus = async (options) => {
|
|
9200
9200
|
const links = resolveLinks(options.links);
|
|
9201
|
+
const statusOptions = options.appStatus && typeof options.appStatus === "object" ? options.appStatus : undefined;
|
|
9202
|
+
const evalOptions = options.evals === false ? undefined : options.evals;
|
|
9203
|
+
const include = statusOptions?.include;
|
|
9204
|
+
const shouldInclude = (surface) => include?.[surface] !== false;
|
|
9201
9205
|
const events = filterVoiceTraceEvents(await options.store.list());
|
|
9202
9206
|
const [quality, workflows, providers, sessions, handoffs] = await Promise.all([
|
|
9203
|
-
options.quality === false ? undefined : evaluateVoiceQuality({
|
|
9207
|
+
options.quality === false || !shouldInclude("quality") ? undefined : evaluateVoiceQuality({
|
|
9204
9208
|
events,
|
|
9205
9209
|
thresholds: options.quality?.thresholds
|
|
9206
9210
|
}),
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
|
|
9211
|
+
!evalOptions || !shouldInclude("workflows") ? undefined : (async () => {
|
|
9212
|
+
const fixtureReport = await runVoiceScenarioFixtureEvals({
|
|
9213
|
+
fixtures: evalOptions.fixtures,
|
|
9214
|
+
fixtureStore: evalOptions.fixtureStore,
|
|
9215
|
+
scenarios: evalOptions.scenarios
|
|
9216
|
+
});
|
|
9217
|
+
if ((statusOptions?.preferFixtureWorkflows ?? true) && fixtureReport.total > 0) {
|
|
9218
|
+
return {
|
|
9219
|
+
failed: fixtureReport.failed,
|
|
9220
|
+
source: "fixtures",
|
|
9221
|
+
status: fixtureReport.status,
|
|
9222
|
+
total: fixtureReport.total
|
|
9223
|
+
};
|
|
9224
|
+
}
|
|
9225
|
+
const liveReport = await runVoiceScenarioEvals({
|
|
9226
|
+
events,
|
|
9227
|
+
scenarios: evalOptions.scenarios
|
|
9228
|
+
});
|
|
9229
|
+
return {
|
|
9230
|
+
failed: liveReport.failed,
|
|
9231
|
+
source: "live",
|
|
9232
|
+
status: liveReport.status,
|
|
9233
|
+
total: liveReport.total
|
|
9234
|
+
};
|
|
9235
|
+
})(),
|
|
9236
|
+
options.providerHealth === false || !shouldInclude("providers") ? undefined : summarizeVoiceProviderHealth({
|
|
9212
9237
|
events,
|
|
9213
9238
|
providers: options.llmProviders
|
|
9214
9239
|
}),
|
|
9215
|
-
options.sessions === false ? undefined : summarizeVoiceSessions({
|
|
9240
|
+
options.sessions === false || !shouldInclude("sessions") ? undefined : summarizeVoiceSessions({
|
|
9216
9241
|
events
|
|
9217
9242
|
}),
|
|
9218
|
-
options.handoffs === false ? undefined : summarizeVoiceHandoffHealth({
|
|
9243
|
+
options.handoffs === false || !shouldInclude("handoffs") ? undefined : summarizeVoiceHandoffHealth({
|
|
9219
9244
|
events
|
|
9220
9245
|
})
|
|
9221
9246
|
]);
|
|
@@ -9229,6 +9254,7 @@ var summarizeVoiceAppKitStatus = async (options) => {
|
|
|
9229
9254
|
const status = workflows.status;
|
|
9230
9255
|
surfaces.workflows = {
|
|
9231
9256
|
failed: workflows.failed,
|
|
9257
|
+
source: workflows.source,
|
|
9232
9258
|
status,
|
|
9233
9259
|
total: workflows.total
|
|
9234
9260
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type VoiceOpsStatusWidgetOptions } from '../client/opsStatusWidget';
|
|
2
|
+
export type VoiceOpsStatusProps = VoiceOpsStatusWidgetOptions & {
|
|
3
|
+
className?: string;
|
|
4
|
+
path?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const VoiceOpsStatus: ({ className, path, ...options }: VoiceOpsStatusProps) => import("react/jsx-runtime").JSX.Element;
|
package/dist/react/index.d.ts
CHANGED
package/dist/react/index.js
CHANGED
|
@@ -167,6 +167,205 @@ var useVoiceAppKitStatus = (path = "/app-kit/status", options = {}) => {
|
|
|
167
167
|
refresh: store.refresh
|
|
168
168
|
};
|
|
169
169
|
};
|
|
170
|
+
|
|
171
|
+
// src/client/opsStatusWidget.ts
|
|
172
|
+
var DEFAULT_TITLE = "Voice Ops Status";
|
|
173
|
+
var DEFAULT_DESCRIPTION = "Certified workflow, provider, and handoff readiness from the AbsoluteJS voice app kit.";
|
|
174
|
+
var SURFACE_LABELS = {
|
|
175
|
+
handoffs: "Handoffs",
|
|
176
|
+
providers: "Providers",
|
|
177
|
+
quality: "Quality",
|
|
178
|
+
sessions: "Sessions",
|
|
179
|
+
workflows: "Workflows"
|
|
180
|
+
};
|
|
181
|
+
var escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
182
|
+
var readNumber = (value, key) => value && typeof value === "object" && (key in value) ? Number(value[key] ?? 0) : 0;
|
|
183
|
+
var surfaceDetail = (surface) => {
|
|
184
|
+
const total = readNumber(surface, "total");
|
|
185
|
+
const failed = readNumber(surface, "failed");
|
|
186
|
+
const degraded = readNumber(surface, "degraded");
|
|
187
|
+
const source = surface && typeof surface === "object" && "source" in surface && typeof surface.source === "string" ? ` from ${surface.source}` : "";
|
|
188
|
+
if (degraded > 0) {
|
|
189
|
+
return `${degraded} degraded of ${total}`;
|
|
190
|
+
}
|
|
191
|
+
if (failed > 0) {
|
|
192
|
+
return `${failed} failing of ${total}${source}`;
|
|
193
|
+
}
|
|
194
|
+
return total > 0 ? `${total} passing${source}` : `No failures${source}`;
|
|
195
|
+
};
|
|
196
|
+
var getVoiceOpsStatusLabel = (report, error) => {
|
|
197
|
+
if (error) {
|
|
198
|
+
return "Unavailable";
|
|
199
|
+
}
|
|
200
|
+
if (!report) {
|
|
201
|
+
return "Checking";
|
|
202
|
+
}
|
|
203
|
+
return report.status === "pass" ? "Passing" : "Needs attention";
|
|
204
|
+
};
|
|
205
|
+
var createVoiceOpsStatusViewModel = (snapshot, options = {}) => {
|
|
206
|
+
const report = snapshot.report;
|
|
207
|
+
const surfaces = Object.entries(report?.surfaces ?? {}).map(([id, surface]) => {
|
|
208
|
+
const failed = readNumber(surface, "failed") || readNumber(surface, "degraded");
|
|
209
|
+
const total = readNumber(surface, "total");
|
|
210
|
+
const status = surface && typeof surface === "object" && "status" in surface ? surface.status ?? "pass" : "pass";
|
|
211
|
+
return {
|
|
212
|
+
detail: surfaceDetail(surface),
|
|
213
|
+
failed,
|
|
214
|
+
id,
|
|
215
|
+
label: SURFACE_LABELS[id] ?? id,
|
|
216
|
+
status,
|
|
217
|
+
total
|
|
218
|
+
};
|
|
219
|
+
});
|
|
220
|
+
return {
|
|
221
|
+
description: options.description ?? DEFAULT_DESCRIPTION,
|
|
222
|
+
error: snapshot.error,
|
|
223
|
+
isLoading: snapshot.isLoading,
|
|
224
|
+
label: getVoiceOpsStatusLabel(report, snapshot.error),
|
|
225
|
+
links: options.includeLinks === false ? [] : report?.links ?? [],
|
|
226
|
+
passed: report?.passed ?? 0,
|
|
227
|
+
status: snapshot.error ? "error" : report ? report.status : snapshot.isLoading ? "loading" : "loading",
|
|
228
|
+
surfaces,
|
|
229
|
+
title: options.title ?? DEFAULT_TITLE,
|
|
230
|
+
total: report?.total ?? 0,
|
|
231
|
+
updatedAt: snapshot.updatedAt
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
var renderVoiceOpsStatusHTML = (snapshot, options = {}) => {
|
|
235
|
+
const model = createVoiceOpsStatusViewModel(snapshot, options);
|
|
236
|
+
const surfaces = model.surfaces.length ? model.surfaces.map((surface) => `<li class="absolute-voice-ops-status__surface absolute-voice-ops-status__surface--${escapeHtml(surface.status)}">
|
|
237
|
+
<span>${escapeHtml(surface.label)}</span>
|
|
238
|
+
<strong>${escapeHtml(surface.detail)}</strong>
|
|
239
|
+
</li>`).join("") : '<li class="absolute-voice-ops-status__surface"><span>Status</span><strong>Waiting for first check</strong></li>';
|
|
240
|
+
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>` : "";
|
|
241
|
+
return `<section class="absolute-voice-ops-status absolute-voice-ops-status--${escapeHtml(model.status)}">
|
|
242
|
+
<header class="absolute-voice-ops-status__header">
|
|
243
|
+
<span class="absolute-voice-ops-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
244
|
+
<strong class="absolute-voice-ops-status__label">${escapeHtml(model.label)}</strong>
|
|
245
|
+
</header>
|
|
246
|
+
<p class="absolute-voice-ops-status__description">${escapeHtml(model.description)}</p>
|
|
247
|
+
<div class="absolute-voice-ops-status__summary">
|
|
248
|
+
<span>${model.passed} passing</span>
|
|
249
|
+
<span>${Math.max(model.total - model.passed, 0)} failing</span>
|
|
250
|
+
<span>${model.total} checks</span>
|
|
251
|
+
</div>
|
|
252
|
+
<ul class="absolute-voice-ops-status__surfaces">${surfaces}</ul>
|
|
253
|
+
${model.error ? `<p class="absolute-voice-ops-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
254
|
+
${links}
|
|
255
|
+
</section>`;
|
|
256
|
+
};
|
|
257
|
+
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}`;
|
|
258
|
+
var mountVoiceOpsStatus = (element, path = "/app-kit/status", options = {}) => {
|
|
259
|
+
const store = createVoiceAppKitStatusStore(path, options);
|
|
260
|
+
const render = () => {
|
|
261
|
+
element.innerHTML = renderVoiceOpsStatusHTML(store.getSnapshot(), options);
|
|
262
|
+
};
|
|
263
|
+
const unsubscribe = store.subscribe(render);
|
|
264
|
+
render();
|
|
265
|
+
store.refresh().catch(() => {});
|
|
266
|
+
return {
|
|
267
|
+
close: () => {
|
|
268
|
+
unsubscribe();
|
|
269
|
+
store.close();
|
|
270
|
+
},
|
|
271
|
+
refresh: store.refresh
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// src/react/VoiceOpsStatus.tsx
|
|
276
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
277
|
+
var VoiceOpsStatus = ({
|
|
278
|
+
className,
|
|
279
|
+
path = "/app-kit/status",
|
|
280
|
+
...options
|
|
281
|
+
}) => {
|
|
282
|
+
const snapshot = useVoiceAppKitStatus(path, options);
|
|
283
|
+
const model = createVoiceOpsStatusViewModel(snapshot, options);
|
|
284
|
+
return /* @__PURE__ */ jsxDEV("section", {
|
|
285
|
+
className: [
|
|
286
|
+
"absolute-voice-ops-status",
|
|
287
|
+
`absolute-voice-ops-status--${model.status}`,
|
|
288
|
+
className
|
|
289
|
+
].filter(Boolean).join(" "),
|
|
290
|
+
children: [
|
|
291
|
+
/* @__PURE__ */ jsxDEV("header", {
|
|
292
|
+
className: "absolute-voice-ops-status__header",
|
|
293
|
+
children: [
|
|
294
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
295
|
+
className: "absolute-voice-ops-status__eyebrow",
|
|
296
|
+
children: model.title
|
|
297
|
+
}, undefined, false, undefined, this),
|
|
298
|
+
/* @__PURE__ */ jsxDEV("strong", {
|
|
299
|
+
className: "absolute-voice-ops-status__label",
|
|
300
|
+
children: model.label
|
|
301
|
+
}, undefined, false, undefined, this)
|
|
302
|
+
]
|
|
303
|
+
}, undefined, true, undefined, this),
|
|
304
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
305
|
+
className: "absolute-voice-ops-status__description",
|
|
306
|
+
children: model.description
|
|
307
|
+
}, undefined, false, undefined, this),
|
|
308
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
309
|
+
className: "absolute-voice-ops-status__summary",
|
|
310
|
+
children: [
|
|
311
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
312
|
+
children: [
|
|
313
|
+
model.passed,
|
|
314
|
+
" passing"
|
|
315
|
+
]
|
|
316
|
+
}, undefined, true, undefined, this),
|
|
317
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
318
|
+
children: [
|
|
319
|
+
Math.max(model.total - model.passed, 0),
|
|
320
|
+
" failing"
|
|
321
|
+
]
|
|
322
|
+
}, undefined, true, undefined, this),
|
|
323
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
324
|
+
children: [
|
|
325
|
+
model.total,
|
|
326
|
+
" checks"
|
|
327
|
+
]
|
|
328
|
+
}, undefined, true, undefined, this)
|
|
329
|
+
]
|
|
330
|
+
}, undefined, true, undefined, this),
|
|
331
|
+
/* @__PURE__ */ jsxDEV("ul", {
|
|
332
|
+
className: "absolute-voice-ops-status__surfaces",
|
|
333
|
+
children: model.surfaces.length > 0 ? model.surfaces.map((surface) => /* @__PURE__ */ jsxDEV("li", {
|
|
334
|
+
className: `absolute-voice-ops-status__surface absolute-voice-ops-status__surface--${surface.status}`,
|
|
335
|
+
children: [
|
|
336
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
337
|
+
children: surface.label
|
|
338
|
+
}, undefined, false, undefined, this),
|
|
339
|
+
/* @__PURE__ */ jsxDEV("strong", {
|
|
340
|
+
children: surface.detail
|
|
341
|
+
}, undefined, false, undefined, this)
|
|
342
|
+
]
|
|
343
|
+
}, surface.id, true, undefined, this)) : /* @__PURE__ */ jsxDEV("li", {
|
|
344
|
+
className: "absolute-voice-ops-status__surface",
|
|
345
|
+
children: [
|
|
346
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
347
|
+
children: "Status"
|
|
348
|
+
}, undefined, false, undefined, this),
|
|
349
|
+
/* @__PURE__ */ jsxDEV("strong", {
|
|
350
|
+
children: "Waiting for first check"
|
|
351
|
+
}, undefined, false, undefined, this)
|
|
352
|
+
]
|
|
353
|
+
}, undefined, true, undefined, this)
|
|
354
|
+
}, undefined, false, undefined, this),
|
|
355
|
+
model.error ? /* @__PURE__ */ jsxDEV("p", {
|
|
356
|
+
className: "absolute-voice-ops-status__error",
|
|
357
|
+
children: model.error
|
|
358
|
+
}, undefined, false, undefined, this) : null,
|
|
359
|
+
model.links.length > 0 ? /* @__PURE__ */ jsxDEV("nav", {
|
|
360
|
+
className: "absolute-voice-ops-status__links",
|
|
361
|
+
children: model.links.slice(0, 4).map((link) => /* @__PURE__ */ jsxDEV("a", {
|
|
362
|
+
href: link.href,
|
|
363
|
+
children: link.label
|
|
364
|
+
}, `${link.label}:${link.href}`, false, undefined, this))
|
|
365
|
+
}, undefined, false, undefined, this) : null
|
|
366
|
+
]
|
|
367
|
+
}, undefined, true, undefined, this);
|
|
368
|
+
};
|
|
170
369
|
// src/react/useVoiceStream.tsx
|
|
171
370
|
import { useEffect as useEffect2, useRef as useRef2, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
172
371
|
|
|
@@ -1580,5 +1779,6 @@ export {
|
|
|
1580
1779
|
useVoiceStream,
|
|
1581
1780
|
useVoiceProviderStatus,
|
|
1582
1781
|
useVoiceController,
|
|
1583
|
-
useVoiceAppKitStatus
|
|
1782
|
+
useVoiceAppKitStatus,
|
|
1783
|
+
VoiceOpsStatus
|
|
1584
1784
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type VoiceOpsStatusWidgetOptions } from '../client/opsStatusWidget';
|
|
2
|
+
export declare const createVoiceOpsStatus: (path?: string, options?: VoiceOpsStatusWidgetOptions) => {
|
|
3
|
+
close: () => void;
|
|
4
|
+
getHTML: () => string;
|
|
5
|
+
getSnapshot: () => import("../client").VoiceAppKitStatusSnapshot;
|
|
6
|
+
getViewModel: () => import("../client").VoiceOpsStatusViewModel;
|
|
7
|
+
refresh: () => Promise<import("..").VoiceAppKitStatusReport | undefined>;
|
|
8
|
+
subscribe: (listener: () => void) => () => void;
|
|
9
|
+
};
|
package/dist/svelte/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createVoiceAppKitStatus } from './createVoiceAppKitStatus';
|
|
2
|
+
export { createVoiceOpsStatus } from './createVoiceOpsStatus';
|
|
2
3
|
export { createVoiceStream } from './createVoiceStream';
|
|
3
4
|
export { createVoiceProviderStatus } from './createVoiceProviderStatus';
|
|
4
5
|
export { createVoiceWorkflowStatus } from './createVoiceWorkflowStatus';
|
package/dist/svelte/index.js
CHANGED
|
@@ -150,6 +150,122 @@ var createVoiceAppKitStatusStore = (path = "/app-kit/status", options = {}) => {
|
|
|
150
150
|
|
|
151
151
|
// src/svelte/createVoiceAppKitStatus.ts
|
|
152
152
|
var createVoiceAppKitStatus = (path = "/app-kit/status", options = {}) => createVoiceAppKitStatusStore(path, options);
|
|
153
|
+
// src/client/opsStatusWidget.ts
|
|
154
|
+
var DEFAULT_TITLE = "Voice Ops Status";
|
|
155
|
+
var DEFAULT_DESCRIPTION = "Certified workflow, provider, and handoff readiness from the AbsoluteJS voice app kit.";
|
|
156
|
+
var SURFACE_LABELS = {
|
|
157
|
+
handoffs: "Handoffs",
|
|
158
|
+
providers: "Providers",
|
|
159
|
+
quality: "Quality",
|
|
160
|
+
sessions: "Sessions",
|
|
161
|
+
workflows: "Workflows"
|
|
162
|
+
};
|
|
163
|
+
var escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
164
|
+
var readNumber = (value, key) => value && typeof value === "object" && (key in value) ? Number(value[key] ?? 0) : 0;
|
|
165
|
+
var surfaceDetail = (surface) => {
|
|
166
|
+
const total = readNumber(surface, "total");
|
|
167
|
+
const failed = readNumber(surface, "failed");
|
|
168
|
+
const degraded = readNumber(surface, "degraded");
|
|
169
|
+
const source = surface && typeof surface === "object" && "source" in surface && typeof surface.source === "string" ? ` from ${surface.source}` : "";
|
|
170
|
+
if (degraded > 0) {
|
|
171
|
+
return `${degraded} degraded of ${total}`;
|
|
172
|
+
}
|
|
173
|
+
if (failed > 0) {
|
|
174
|
+
return `${failed} failing of ${total}${source}`;
|
|
175
|
+
}
|
|
176
|
+
return total > 0 ? `${total} passing${source}` : `No failures${source}`;
|
|
177
|
+
};
|
|
178
|
+
var getVoiceOpsStatusLabel = (report, error) => {
|
|
179
|
+
if (error) {
|
|
180
|
+
return "Unavailable";
|
|
181
|
+
}
|
|
182
|
+
if (!report) {
|
|
183
|
+
return "Checking";
|
|
184
|
+
}
|
|
185
|
+
return report.status === "pass" ? "Passing" : "Needs attention";
|
|
186
|
+
};
|
|
187
|
+
var createVoiceOpsStatusViewModel = (snapshot, options = {}) => {
|
|
188
|
+
const report = snapshot.report;
|
|
189
|
+
const surfaces = Object.entries(report?.surfaces ?? {}).map(([id, surface]) => {
|
|
190
|
+
const failed = readNumber(surface, "failed") || readNumber(surface, "degraded");
|
|
191
|
+
const total = readNumber(surface, "total");
|
|
192
|
+
const status = surface && typeof surface === "object" && "status" in surface ? surface.status ?? "pass" : "pass";
|
|
193
|
+
return {
|
|
194
|
+
detail: surfaceDetail(surface),
|
|
195
|
+
failed,
|
|
196
|
+
id,
|
|
197
|
+
label: SURFACE_LABELS[id] ?? id,
|
|
198
|
+
status,
|
|
199
|
+
total
|
|
200
|
+
};
|
|
201
|
+
});
|
|
202
|
+
return {
|
|
203
|
+
description: options.description ?? DEFAULT_DESCRIPTION,
|
|
204
|
+
error: snapshot.error,
|
|
205
|
+
isLoading: snapshot.isLoading,
|
|
206
|
+
label: getVoiceOpsStatusLabel(report, snapshot.error),
|
|
207
|
+
links: options.includeLinks === false ? [] : report?.links ?? [],
|
|
208
|
+
passed: report?.passed ?? 0,
|
|
209
|
+
status: snapshot.error ? "error" : report ? report.status : snapshot.isLoading ? "loading" : "loading",
|
|
210
|
+
surfaces,
|
|
211
|
+
title: options.title ?? DEFAULT_TITLE,
|
|
212
|
+
total: report?.total ?? 0,
|
|
213
|
+
updatedAt: snapshot.updatedAt
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
var renderVoiceOpsStatusHTML = (snapshot, options = {}) => {
|
|
217
|
+
const model = createVoiceOpsStatusViewModel(snapshot, options);
|
|
218
|
+
const surfaces = model.surfaces.length ? model.surfaces.map((surface) => `<li class="absolute-voice-ops-status__surface absolute-voice-ops-status__surface--${escapeHtml(surface.status)}">
|
|
219
|
+
<span>${escapeHtml(surface.label)}</span>
|
|
220
|
+
<strong>${escapeHtml(surface.detail)}</strong>
|
|
221
|
+
</li>`).join("") : '<li class="absolute-voice-ops-status__surface"><span>Status</span><strong>Waiting for first check</strong></li>';
|
|
222
|
+
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>` : "";
|
|
223
|
+
return `<section class="absolute-voice-ops-status absolute-voice-ops-status--${escapeHtml(model.status)}">
|
|
224
|
+
<header class="absolute-voice-ops-status__header">
|
|
225
|
+
<span class="absolute-voice-ops-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
226
|
+
<strong class="absolute-voice-ops-status__label">${escapeHtml(model.label)}</strong>
|
|
227
|
+
</header>
|
|
228
|
+
<p class="absolute-voice-ops-status__description">${escapeHtml(model.description)}</p>
|
|
229
|
+
<div class="absolute-voice-ops-status__summary">
|
|
230
|
+
<span>${model.passed} passing</span>
|
|
231
|
+
<span>${Math.max(model.total - model.passed, 0)} failing</span>
|
|
232
|
+
<span>${model.total} checks</span>
|
|
233
|
+
</div>
|
|
234
|
+
<ul class="absolute-voice-ops-status__surfaces">${surfaces}</ul>
|
|
235
|
+
${model.error ? `<p class="absolute-voice-ops-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
236
|
+
${links}
|
|
237
|
+
</section>`;
|
|
238
|
+
};
|
|
239
|
+
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}`;
|
|
240
|
+
var mountVoiceOpsStatus = (element, path = "/app-kit/status", options = {}) => {
|
|
241
|
+
const store = createVoiceAppKitStatusStore(path, options);
|
|
242
|
+
const render = () => {
|
|
243
|
+
element.innerHTML = renderVoiceOpsStatusHTML(store.getSnapshot(), options);
|
|
244
|
+
};
|
|
245
|
+
const unsubscribe = store.subscribe(render);
|
|
246
|
+
render();
|
|
247
|
+
store.refresh().catch(() => {});
|
|
248
|
+
return {
|
|
249
|
+
close: () => {
|
|
250
|
+
unsubscribe();
|
|
251
|
+
store.close();
|
|
252
|
+
},
|
|
253
|
+
refresh: store.refresh
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
// src/svelte/createVoiceOpsStatus.ts
|
|
258
|
+
var createVoiceOpsStatus = (path = "/app-kit/status", options = {}) => {
|
|
259
|
+
const store = createVoiceAppKitStatusStore(path, options);
|
|
260
|
+
return {
|
|
261
|
+
close: store.close,
|
|
262
|
+
getHTML: () => renderVoiceOpsStatusHTML(store.getSnapshot(), options),
|
|
263
|
+
getSnapshot: store.getSnapshot,
|
|
264
|
+
getViewModel: () => createVoiceOpsStatusViewModel(store.getSnapshot(), options),
|
|
265
|
+
refresh: store.refresh,
|
|
266
|
+
subscribe: store.subscribe
|
|
267
|
+
};
|
|
268
|
+
};
|
|
153
269
|
// src/client/actions.ts
|
|
154
270
|
var normalizeErrorMessage = (value) => {
|
|
155
271
|
if (typeof value === "string" && value.trim()) {
|
|
@@ -1461,6 +1577,7 @@ export {
|
|
|
1461
1577
|
createVoiceWorkflowStatus,
|
|
1462
1578
|
createVoiceStream2 as createVoiceStream,
|
|
1463
1579
|
createVoiceProviderStatus,
|
|
1580
|
+
createVoiceOpsStatus,
|
|
1464
1581
|
createVoiceController,
|
|
1465
1582
|
createVoiceAppKitStatus
|
|
1466
1583
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare const VoiceOpsStatus: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
2
|
+
description: StringConstructor;
|
|
3
|
+
includeLinks: {
|
|
4
|
+
default: boolean;
|
|
5
|
+
type: BooleanConstructor;
|
|
6
|
+
};
|
|
7
|
+
intervalMs: NumberConstructor;
|
|
8
|
+
path: {
|
|
9
|
+
default: string;
|
|
10
|
+
type: StringConstructor;
|
|
11
|
+
};
|
|
12
|
+
title: StringConstructor;
|
|
13
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
16
|
+
description: StringConstructor;
|
|
17
|
+
includeLinks: {
|
|
18
|
+
default: boolean;
|
|
19
|
+
type: BooleanConstructor;
|
|
20
|
+
};
|
|
21
|
+
intervalMs: NumberConstructor;
|
|
22
|
+
path: {
|
|
23
|
+
default: string;
|
|
24
|
+
type: StringConstructor;
|
|
25
|
+
};
|
|
26
|
+
title: StringConstructor;
|
|
27
|
+
}>> & Readonly<{}>, {
|
|
28
|
+
path: string;
|
|
29
|
+
includeLinks: boolean;
|
|
30
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
package/dist/vue/index.d.ts
CHANGED