@absolutejs/voice 0.0.22-beta.333 → 0.0.22-beta.335
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/client/index.js +433 -168
- package/dist/index.d.ts +2 -2
- package/dist/index.js +555 -286
- package/dist/proofTrends.d.ts +107 -0
- package/dist/react/index.js +393 -128
- package/dist/vue/index.js +368 -103
- package/package.json +1 -1
package/dist/client/index.js
CHANGED
|
@@ -3821,7 +3821,7 @@ var maxNumber = (values) => {
|
|
|
3821
3821
|
return finite.length > 0 ? Math.max(...finite) : undefined;
|
|
3822
3822
|
};
|
|
3823
3823
|
var readProofTrendMaxLiveP95 = (report) => report.summary.maxLiveP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.liveLatency?.p95Ms));
|
|
3824
|
-
var readProofTrendMaxProviderP95 = (report) => report.summary.maxProviderP95Ms;
|
|
3824
|
+
var readProofTrendMaxProviderP95 = (report) => report.summary.maxProviderP95Ms ?? maxNumber((report.summary.providers ?? []).map((provider) => provider.p95Ms)) ?? maxNumber(report.cycles.flatMap((cycle) => (cycle.providers ?? []).map((provider) => provider.p95Ms)));
|
|
3825
3825
|
var readProofTrendMaxTurnP95 = (report) => report.summary.maxTurnP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.turnLatency?.p95Ms));
|
|
3826
3826
|
var readRuntimeChannelMetric = (report, key) => {
|
|
3827
3827
|
const summaryValue = report.summary.runtimeChannel?.[key];
|
|
@@ -3839,6 +3839,91 @@ var readProofTrendRuntimeChannel = (report) => ({
|
|
|
3839
3839
|
samples: report.summary.runtimeChannel?.samples ?? maxNumber(report.cycles.map((cycle) => cycle.runtimeChannel?.samples)),
|
|
3840
3840
|
status: report.summary.runtimeChannel?.status
|
|
3841
3841
|
});
|
|
3842
|
+
var normalizeProviderStatus = (status) => status === "pass" ? "pass" : status === "fail" ? "fail" : "warn";
|
|
3843
|
+
var providerSortScore = (provider) => [
|
|
3844
|
+
recommendationStatusRank[provider.status],
|
|
3845
|
+
provider.p95Ms ?? Number.POSITIVE_INFINITY,
|
|
3846
|
+
provider.averageMs ?? Number.POSITIVE_INFINITY,
|
|
3847
|
+
provider.samples === undefined ? Number.POSITIVE_INFINITY : -provider.samples,
|
|
3848
|
+
provider.id
|
|
3849
|
+
];
|
|
3850
|
+
var compareProviders = (left, right) => {
|
|
3851
|
+
const leftScore = providerSortScore(left);
|
|
3852
|
+
const rightScore = providerSortScore(right);
|
|
3853
|
+
for (let index = 0;index < leftScore.length; index += 1) {
|
|
3854
|
+
const leftValue = leftScore[index];
|
|
3855
|
+
const rightValue = rightScore[index];
|
|
3856
|
+
if (typeof leftValue === "number" && typeof rightValue === "number") {
|
|
3857
|
+
if (leftValue !== rightValue) {
|
|
3858
|
+
return leftValue - rightValue;
|
|
3859
|
+
}
|
|
3860
|
+
continue;
|
|
3861
|
+
}
|
|
3862
|
+
const compared = String(leftValue).localeCompare(String(rightValue));
|
|
3863
|
+
if (compared !== 0) {
|
|
3864
|
+
return compared;
|
|
3865
|
+
}
|
|
3866
|
+
}
|
|
3867
|
+
return 0;
|
|
3868
|
+
};
|
|
3869
|
+
var summarizeProofTrendProviders = (report, budgetMs) => {
|
|
3870
|
+
const sourceProviders = report.summary.providers && report.summary.providers.length > 0 ? report.summary.providers : undefined;
|
|
3871
|
+
const providersById = new Map;
|
|
3872
|
+
if (sourceProviders) {
|
|
3873
|
+
for (const provider of sourceProviders) {
|
|
3874
|
+
if (provider.id) {
|
|
3875
|
+
providersById.set(provider.id, provider);
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
} else {
|
|
3879
|
+
for (const cycle of report.cycles) {
|
|
3880
|
+
for (const provider of cycle.providers ?? []) {
|
|
3881
|
+
if (!provider.id) {
|
|
3882
|
+
continue;
|
|
3883
|
+
}
|
|
3884
|
+
const existing = providersById.get(provider.id);
|
|
3885
|
+
providersById.set(provider.id, {
|
|
3886
|
+
averageMs: maxNumber([existing?.averageMs, provider.averageMs]),
|
|
3887
|
+
id: provider.id,
|
|
3888
|
+
label: existing?.label ?? provider.label,
|
|
3889
|
+
p50Ms: maxNumber([existing?.p50Ms, provider.p50Ms]),
|
|
3890
|
+
p95Ms: maxNumber([existing?.p95Ms, provider.p95Ms]),
|
|
3891
|
+
role: existing?.role ?? provider.role,
|
|
3892
|
+
samples: (existing?.samples ?? 0) + (provider.samples ?? 0),
|
|
3893
|
+
status: existing?.status === "fail" || provider.status === "fail" ? "fail" : existing?.status === "warn" || provider.status === "warn" ? "warn" : provider.status ?? existing?.status
|
|
3894
|
+
});
|
|
3895
|
+
}
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
3898
|
+
return [...providersById.values()].map((provider) => {
|
|
3899
|
+
const status = provider.p95Ms === undefined ? normalizeProviderStatus(provider.status) : withinBudget(provider.p95Ms, budgetMs) ? normalizeProviderStatus(provider.status) === "fail" ? "fail" : "pass" : normalizeProviderStatus(provider.status) === "fail" ? "fail" : "warn";
|
|
3900
|
+
return {
|
|
3901
|
+
averageMs: provider.averageMs,
|
|
3902
|
+
id: provider.id,
|
|
3903
|
+
label: provider.label,
|
|
3904
|
+
nextMove: status === "pass" ? "Eligible for latency-sensitive routing based on sustained proof." : provider.p95Ms === undefined ? "Collect provider-specific latency samples before routing latency-sensitive traffic here." : "Keep as fallback or tune provider/model/runtime budgets before using for latency-sensitive routing.",
|
|
3905
|
+
p50Ms: provider.p50Ms,
|
|
3906
|
+
p95Ms: provider.p95Ms,
|
|
3907
|
+
rank: 0,
|
|
3908
|
+
role: provider.role,
|
|
3909
|
+
samples: provider.samples,
|
|
3910
|
+
status
|
|
3911
|
+
};
|
|
3912
|
+
}).sort(compareProviders).map((provider, index) => ({ ...provider, rank: index + 1 }));
|
|
3913
|
+
};
|
|
3914
|
+
var shouldSwitchProvider = (current, best, options) => {
|
|
3915
|
+
if (!current || !best || current.id === best.id || best.status !== "pass") {
|
|
3916
|
+
return false;
|
|
3917
|
+
}
|
|
3918
|
+
if (current.p95Ms === undefined || best.p95Ms === undefined) {
|
|
3919
|
+
return false;
|
|
3920
|
+
}
|
|
3921
|
+
const minImprovementMs = options.providerSwitchMinImprovementMs ?? 100;
|
|
3922
|
+
const minImprovementRatio = options.providerSwitchMinImprovementRatio ?? 0.1;
|
|
3923
|
+
const improvementMs = current.p95Ms - best.p95Ms;
|
|
3924
|
+
const improvementRatio = current.p95Ms > 0 ? improvementMs / current.p95Ms : 0;
|
|
3925
|
+
return improvementMs >= minImprovementMs || improvementRatio >= minImprovementRatio;
|
|
3926
|
+
};
|
|
3842
3927
|
var evaluateVoiceProofTrendEvidence = (report, input = {}) => {
|
|
3843
3928
|
const issues = [];
|
|
3844
3929
|
const requiredStatus = input.requireStatus ?? "pass";
|
|
@@ -3930,6 +4015,186 @@ var assertVoiceProofTrendEvidence = (report, input = {}) => {
|
|
|
3930
4015
|
}
|
|
3931
4016
|
return assertion;
|
|
3932
4017
|
};
|
|
4018
|
+
var DEFAULT_RECOMMENDATION_BUDGETS = {
|
|
4019
|
+
maxLiveP95Ms: 800,
|
|
4020
|
+
maxProviderP95Ms: 1000,
|
|
4021
|
+
maxRuntimeBackpressureEvents: 0,
|
|
4022
|
+
maxRuntimeFirstAudioLatencyMs: 600,
|
|
4023
|
+
maxRuntimeInterruptionP95Ms: 300,
|
|
4024
|
+
maxRuntimeJitterMs: 30,
|
|
4025
|
+
maxRuntimeTimestampDriftMs: 800,
|
|
4026
|
+
maxTurnP95Ms: 700
|
|
4027
|
+
};
|
|
4028
|
+
var withinBudget = (value, budget) => typeof value === "number" && Number.isFinite(value) && value <= budget;
|
|
4029
|
+
var recommendationStatusRank = {
|
|
4030
|
+
pass: 0,
|
|
4031
|
+
warn: 1,
|
|
4032
|
+
fail: 2
|
|
4033
|
+
};
|
|
4034
|
+
var worstRecommendationStatus = (recommendations) => recommendations.reduce((status, recommendation) => recommendationStatusRank[recommendation.status] > recommendationStatusRank[status] ? recommendation.status : status, "pass");
|
|
4035
|
+
var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
4036
|
+
const budgets = { ...DEFAULT_RECOMMENDATION_BUDGETS, ...options };
|
|
4037
|
+
const maxLiveP95Ms = readProofTrendMaxLiveP95(report);
|
|
4038
|
+
const maxProviderP95Ms = readProofTrendMaxProviderP95(report);
|
|
4039
|
+
const maxTurnP95Ms = readProofTrendMaxTurnP95(report);
|
|
4040
|
+
const runtimeChannel = readProofTrendRuntimeChannel(report);
|
|
4041
|
+
const providers = summarizeProofTrendProviders(report, budgets.maxProviderP95Ms);
|
|
4042
|
+
const bestProvider = providers.find((provider) => provider.status === "pass") ?? providers[0];
|
|
4043
|
+
const currentProvider = options.currentProviderId ? providers.find((provider) => provider.id === options.currentProviderId) : undefined;
|
|
4044
|
+
const providerSwitchRecommended = shouldSwitchProvider(currentProvider, bestProvider, options);
|
|
4045
|
+
const recommendations = [];
|
|
4046
|
+
const issues = [];
|
|
4047
|
+
if (report.ok !== true) {
|
|
4048
|
+
issues.push(`Proof trend report is ${report.status}; recommendations need a fresh passing trend artifact.`);
|
|
4049
|
+
}
|
|
4050
|
+
recommendations.push({
|
|
4051
|
+
evidence: {
|
|
4052
|
+
bestProviderId: bestProvider?.id,
|
|
4053
|
+
bestProviderP95Ms: bestProvider?.p95Ms,
|
|
4054
|
+
budgetMs: budgets.maxProviderP95Ms,
|
|
4055
|
+
currentProviderId: currentProvider?.id ?? options.currentProviderId,
|
|
4056
|
+
currentProviderP95Ms: currentProvider?.p95Ms,
|
|
4057
|
+
providerComparisonCount: providers.length,
|
|
4058
|
+
providerP95Ms: maxProviderP95Ms
|
|
4059
|
+
},
|
|
4060
|
+
nextMove: providers.length > 0 ? providerSwitchRecommended ? `Route latency-sensitive turns to ${bestProvider?.label ?? bestProvider?.id} for this call profile and keep the current path as fallback.` : bestProvider ? `Use ${bestProvider.label ?? bestProvider.id} as the fastest proven provider path for this call profile and keep collecting sustained comparisons.` : "Collect provider-specific sustained samples before making provider-specific routing decisions." : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep the current provider route for latency-sensitive turns and keep collecting sustained proof." : "Route latency-sensitive turns to a faster provider profile or tighten fallback/circuit-breaker budgets before promotion.",
|
|
4061
|
+
providerId: bestProvider?.id,
|
|
4062
|
+
recommendation: providers.length > 0 ? providerSwitchRecommended ? `Switch latency-sensitive routing to ${bestProvider?.label ?? bestProvider?.id}` : bestProvider ? `Prefer ${bestProvider.label ?? bestProvider.id} for this call profile` : "Collect provider-specific latency samples" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep current provider path" : "Change provider routing for latency-sensitive traffic",
|
|
4063
|
+
role: bestProvider?.role,
|
|
4064
|
+
status: providers.length > 0 ? providerSwitchRecommended ? "warn" : bestProvider?.status ?? "fail" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
|
|
4065
|
+
surface: "provider-path"
|
|
4066
|
+
});
|
|
4067
|
+
const runtimePass = withinBudget(runtimeChannel.maxFirstAudioLatencyMs, budgets.maxRuntimeFirstAudioLatencyMs) && withinBudget(runtimeChannel.maxInterruptionP95Ms, budgets.maxRuntimeInterruptionP95Ms) && withinBudget(runtimeChannel.maxJitterMs, budgets.maxRuntimeJitterMs) && withinBudget(runtimeChannel.maxTimestampDriftMs, budgets.maxRuntimeTimestampDriftMs) && withinBudget(runtimeChannel.maxBackpressureEvents, budgets.maxRuntimeBackpressureEvents);
|
|
4068
|
+
recommendations.push({
|
|
4069
|
+
evidence: {
|
|
4070
|
+
backpressureEvents: runtimeChannel.maxBackpressureEvents,
|
|
4071
|
+
firstAudioBudgetMs: budgets.maxRuntimeFirstAudioLatencyMs,
|
|
4072
|
+
firstAudioMs: runtimeChannel.maxFirstAudioLatencyMs,
|
|
4073
|
+
interruptionBudgetMs: budgets.maxRuntimeInterruptionP95Ms,
|
|
4074
|
+
interruptionP95Ms: runtimeChannel.maxInterruptionP95Ms,
|
|
4075
|
+
jitterBudgetMs: budgets.maxRuntimeJitterMs,
|
|
4076
|
+
jitterMs: runtimeChannel.maxJitterMs,
|
|
4077
|
+
samples: runtimeChannel.samples,
|
|
4078
|
+
timestampDriftMs: runtimeChannel.maxTimestampDriftMs
|
|
4079
|
+
},
|
|
4080
|
+
nextMove: runtimePass ? "Keep the current runtime-channel settings and use this artifact as the deploy gate baseline." : "Tune capture/output format, buffering, interruption threshold, or transport backpressure before promoting this runtime path.",
|
|
4081
|
+
recommendation: runtimePass ? "Keep current runtime channel" : "Tune runtime channel before promotion",
|
|
4082
|
+
status: runtimePass ? "pass" : runtimeChannel.samples === undefined ? "fail" : "warn",
|
|
4083
|
+
surface: "runtime-channel"
|
|
4084
|
+
});
|
|
4085
|
+
recommendations.push({
|
|
4086
|
+
evidence: {
|
|
4087
|
+
budgetMs: budgets.maxLiveP95Ms,
|
|
4088
|
+
liveP95Ms: maxLiveP95Ms
|
|
4089
|
+
},
|
|
4090
|
+
nextMove: withinBudget(maxLiveP95Ms, budgets.maxLiveP95Ms) ? "Keep browser live-latency defaults and continue watching long-window drift." : "Tune browser streaming, chunking, or readiness thresholds before release.",
|
|
4091
|
+
recommendation: withinBudget(maxLiveP95Ms, budgets.maxLiveP95Ms) ? "Keep live-latency settings" : "Tune live-latency path",
|
|
4092
|
+
status: withinBudget(maxLiveP95Ms, budgets.maxLiveP95Ms) ? "pass" : maxLiveP95Ms === undefined ? "fail" : "warn",
|
|
4093
|
+
surface: "live-latency"
|
|
4094
|
+
});
|
|
4095
|
+
recommendations.push({
|
|
4096
|
+
evidence: {
|
|
4097
|
+
budgetMs: budgets.maxTurnP95Ms,
|
|
4098
|
+
turnP95Ms: maxTurnP95Ms
|
|
4099
|
+
},
|
|
4100
|
+
nextMove: withinBudget(maxTurnP95Ms, budgets.maxTurnP95Ms) ? "Keep current turn pipeline defaults." : "Reduce tool/provider latency or split the turn pipeline before promotion.",
|
|
4101
|
+
recommendation: withinBudget(maxTurnP95Ms, budgets.maxTurnP95Ms) ? "Keep turn pipeline" : "Tune turn pipeline",
|
|
4102
|
+
status: withinBudget(maxTurnP95Ms, budgets.maxTurnP95Ms) ? "pass" : maxTurnP95Ms === undefined ? "fail" : "warn",
|
|
4103
|
+
surface: "turn-latency"
|
|
4104
|
+
});
|
|
4105
|
+
const status = issues.length > 0 ? "fail" : worstRecommendationStatus(recommendations);
|
|
4106
|
+
return {
|
|
4107
|
+
bestProvider,
|
|
4108
|
+
generatedAt: new Date().toISOString(),
|
|
4109
|
+
issues,
|
|
4110
|
+
ok: status !== "fail",
|
|
4111
|
+
providers,
|
|
4112
|
+
recommendations,
|
|
4113
|
+
source: report.source || report.outputDir || report.runId || "proof-trends",
|
|
4114
|
+
status,
|
|
4115
|
+
summary: {
|
|
4116
|
+
keepCurrentProviderPath: !providerSwitchRecommended && recommendations.find((item) => item.surface === "provider-path")?.status !== "fail",
|
|
4117
|
+
keepCurrentRuntimeChannel: recommendations.find((item) => item.surface === "runtime-channel")?.status === "pass",
|
|
4118
|
+
providerComparisonCount: providers.length,
|
|
4119
|
+
recommendedActions: recommendations.filter((item) => item.status !== "pass").length,
|
|
4120
|
+
switchRecommended: providerSwitchRecommended
|
|
4121
|
+
}
|
|
4122
|
+
};
|
|
4123
|
+
};
|
|
4124
|
+
var escapeHtml3 = (value) => String(value).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
4125
|
+
var escapeMarkdown = (value) => value.replaceAll("|", "\\|");
|
|
4126
|
+
var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provider Runtime Recommendations") => [
|
|
4127
|
+
`# ${title}`,
|
|
4128
|
+
"",
|
|
4129
|
+
`- Status: ${report.status}`,
|
|
4130
|
+
`- Source: ${report.source}`,
|
|
4131
|
+
`- Best provider: ${report.bestProvider?.label ?? report.bestProvider?.id ?? "n/a"}`,
|
|
4132
|
+
`- Provider comparisons: ${String(report.summary.providerComparisonCount)}`,
|
|
4133
|
+
`- Recommended actions: ${String(report.summary.recommendedActions)}`,
|
|
4134
|
+
"",
|
|
4135
|
+
"| Surface | Status | Recommendation | Next move |",
|
|
4136
|
+
"| --- | --- | --- | --- |",
|
|
4137
|
+
...report.recommendations.map((recommendation) => `| ${escapeMarkdown(recommendation.surface)} | ${recommendation.status} | ${escapeMarkdown(recommendation.recommendation)} | ${escapeMarkdown(recommendation.nextMove)} |`),
|
|
4138
|
+
"",
|
|
4139
|
+
"## Provider Comparison",
|
|
4140
|
+
"",
|
|
4141
|
+
"| Rank | Provider | Role | Status | P95 | Samples | Next move |",
|
|
4142
|
+
"| ---: | --- | --- | --- | ---: | ---: | --- |",
|
|
4143
|
+
...report.providers.length ? report.providers.map((provider) => `| ${String(provider.rank)} | ${escapeMarkdown(provider.label ?? provider.id)} | ${escapeMarkdown(provider.role ?? "n/a")} | ${provider.status} | ${provider.p95Ms === undefined ? "n/a" : String(provider.p95Ms)} | ${provider.samples === undefined ? "n/a" : String(provider.samples)} | ${escapeMarkdown(provider.nextMove)} |`) : ["| n/a | n/a | n/a | n/a | n/a | n/a | No provider-specific samples were present. |"],
|
|
4144
|
+
"",
|
|
4145
|
+
"## Issues",
|
|
4146
|
+
"",
|
|
4147
|
+
...report.issues.length ? report.issues.map((issue) => `- ${issue}`) : ["- None"]
|
|
4148
|
+
].join(`
|
|
4149
|
+
`);
|
|
4150
|
+
var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider Runtime Recommendations") => {
|
|
4151
|
+
const cards = report.recommendations.map((recommendation) => `<article class="${escapeHtml3(recommendation.status)}"><p class="eyebrow">${escapeHtml3(recommendation.surface)} \xB7 ${escapeHtml3(recommendation.status)}</p><h2>${escapeHtml3(recommendation.recommendation)}</h2><p>${escapeHtml3(recommendation.nextMove)}</p><pre>${escapeHtml3(JSON.stringify(recommendation.evidence, null, 2))}</pre></article>`).join("");
|
|
4152
|
+
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml3(issue)}</li>`).join("");
|
|
4153
|
+
const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${escapeHtml3(provider.label ?? provider.id)}</strong><span>${escapeHtml3(provider.role ?? "provider")} \xB7 ${escapeHtml3(provider.status)} \xB7 p95 ${escapeHtml3(provider.p95Ms ?? "n/a")}ms \xB7 ${escapeHtml3(provider.samples ?? "n/a")} sample(s)</span><small>${escapeHtml3(provider.nextMove)}</small></li>`).join("");
|
|
4154
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml3(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml3(title)}</h1><p>Generated ${escapeHtml3(report.generatedAt)} from ${escapeHtml3(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml3(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best ${escapeHtml3(report.bestProvider?.label ?? report.bestProvider?.id ?? "n/a")}</span><span class="pill">Runtime ${report.summary.keepCurrentRuntimeChannel ? "keep" : "tune"}</span><span class="pill">${String(report.summary.recommendedActions)} action(s)</span></div></section>${cards}<section class="hero"><h2>Provider Comparison</h2><ul>${providerRows}</ul></section><section class="hero"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
|
|
4155
|
+
};
|
|
4156
|
+
var createVoiceProofTrendRecommendationRoutes = (options) => {
|
|
4157
|
+
const path = options.path ?? "/api/voice/proof-trend-recommendations";
|
|
4158
|
+
const htmlPath = options.htmlPath === undefined ? "/voice/proof-trend-recommendations" : options.htmlPath;
|
|
4159
|
+
const markdownPath = options.markdownPath === undefined ? "/voice/proof-trend-recommendations.md" : options.markdownPath;
|
|
4160
|
+
const title = options.title ?? "Voice Provider Runtime Recommendations";
|
|
4161
|
+
const routes = new Elysia({
|
|
4162
|
+
name: options.name ?? "absolutejs-voice-proof-trend-recommendations"
|
|
4163
|
+
});
|
|
4164
|
+
const loadReport = async () => {
|
|
4165
|
+
const value = options.source !== undefined ? typeof options.source === "function" ? await options.source() : options.source : options.jsonPath ? await readVoiceProofTrendReportFile(options.jsonPath, {
|
|
4166
|
+
maxAgeMs: options.maxAgeMs
|
|
4167
|
+
}) : buildEmptyVoiceProofTrendReport("", options.maxAgeMs);
|
|
4168
|
+
return buildVoiceProofTrendRecommendationReport(normalizeVoiceProofTrendReport(value, {
|
|
4169
|
+
maxAgeMs: options.maxAgeMs,
|
|
4170
|
+
source: options.jsonPath
|
|
4171
|
+
}), options);
|
|
4172
|
+
};
|
|
4173
|
+
routes.get(path, async () => Response.json(await loadReport(), { headers: options.headers }));
|
|
4174
|
+
if (htmlPath !== false) {
|
|
4175
|
+
routes.get(htmlPath, async () => {
|
|
4176
|
+
const report = await loadReport();
|
|
4177
|
+
return new Response(renderVoiceProofTrendRecommendationHTML(report, title), {
|
|
4178
|
+
headers: {
|
|
4179
|
+
"content-type": "text/html; charset=utf-8",
|
|
4180
|
+
...Object.fromEntries(new Headers(options.headers))
|
|
4181
|
+
}
|
|
4182
|
+
});
|
|
4183
|
+
});
|
|
4184
|
+
}
|
|
4185
|
+
if (markdownPath !== false) {
|
|
4186
|
+
routes.get(markdownPath, async () => {
|
|
4187
|
+
const report = await loadReport();
|
|
4188
|
+
return new Response(renderVoiceProofTrendRecommendationMarkdown(report, title), {
|
|
4189
|
+
headers: {
|
|
4190
|
+
"content-type": "text/markdown; charset=utf-8",
|
|
4191
|
+
...Object.fromEntries(new Headers(options.headers))
|
|
4192
|
+
}
|
|
4193
|
+
});
|
|
4194
|
+
});
|
|
4195
|
+
}
|
|
4196
|
+
return routes;
|
|
4197
|
+
};
|
|
3933
4198
|
var createVoiceProofTrendRoutes = (options) => {
|
|
3934
4199
|
const path = options.path ?? "/api/voice/proof-trends";
|
|
3935
4200
|
const routes = new Elysia({
|
|
@@ -3972,7 +4237,7 @@ var DEFAULT_LINKS2 = [
|
|
|
3972
4237
|
{ href: "/voice/proof-trends", label: "Trend page" },
|
|
3973
4238
|
{ href: "/api/voice/proof-trends", label: "Trend JSON" }
|
|
3974
4239
|
];
|
|
3975
|
-
var
|
|
4240
|
+
var escapeHtml4 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3976
4241
|
var formatMs = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
3977
4242
|
var statusLabel = (report) => {
|
|
3978
4243
|
if (!report) {
|
|
@@ -4022,19 +4287,19 @@ var createVoiceProofTrendsViewModel = (snapshot, options = {}) => {
|
|
|
4022
4287
|
var renderVoiceProofTrendsHTML = (snapshot, options = {}) => {
|
|
4023
4288
|
const model = createVoiceProofTrendsViewModel(snapshot, options);
|
|
4024
4289
|
const metrics = model.metrics.length ? `<div class="absolute-voice-proof-trends__metrics">${model.metrics.map((metric) => `<article>
|
|
4025
|
-
<span>${
|
|
4026
|
-
<strong>${
|
|
4027
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ?
|
|
4028
|
-
const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${
|
|
4029
|
-
return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${
|
|
4290
|
+
<span>${escapeHtml4(metric.label)}</span>
|
|
4291
|
+
<strong>${escapeHtml4(metric.value)}</strong>
|
|
4292
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ? escapeHtml4(model.error) : "Run the sustained proof trends script to populate evidence."}</p>`;
|
|
4293
|
+
const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${escapeHtml4(link.href)}">${escapeHtml4(link.label)}</a>`).join("")}</p>` : "";
|
|
4294
|
+
return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${escapeHtml4(model.status)}">
|
|
4030
4295
|
<header class="absolute-voice-proof-trends__header">
|
|
4031
|
-
<span class="absolute-voice-proof-trends__eyebrow">${
|
|
4032
|
-
<strong class="absolute-voice-proof-trends__label">${
|
|
4296
|
+
<span class="absolute-voice-proof-trends__eyebrow">${escapeHtml4(model.title)}</span>
|
|
4297
|
+
<strong class="absolute-voice-proof-trends__label">${escapeHtml4(model.label)}</strong>
|
|
4033
4298
|
</header>
|
|
4034
|
-
<p class="absolute-voice-proof-trends__description">${
|
|
4299
|
+
<p class="absolute-voice-proof-trends__description">${escapeHtml4(model.description)}</p>
|
|
4035
4300
|
${metrics}
|
|
4036
4301
|
${links}
|
|
4037
|
-
${model.error ? `<p class="absolute-voice-proof-trends__error">${
|
|
4302
|
+
${model.error ? `<p class="absolute-voice-proof-trends__error">${escapeHtml4(model.error)}</p>` : ""}
|
|
4038
4303
|
</section>`;
|
|
4039
4304
|
};
|
|
4040
4305
|
var getVoiceProofTrendsCSS = () => `.absolute-voice-proof-trends{border:1px solid #99f6e4;border-radius:20px;background:#f0fdfa;color:#0f172a;padding:18px;box-shadow:0 18px 40px rgba(13,148,136,.12);font-family:inherit}.absolute-voice-proof-trends--warning,.absolute-voice-proof-trends--error{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-proof-trends__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-proof-trends__eyebrow{color:#0f766e;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-proof-trends__label{font-size:24px;line-height:1}.absolute-voice-proof-trends__description,.absolute-voice-proof-trends__empty{color:#475569}.absolute-voice-proof-trends__metrics{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));margin-top:14px}.absolute-voice-proof-trends__metrics article{background:#fff;border:1px solid #ccfbf1;border-radius:16px;padding:12px}.absolute-voice-proof-trends__metrics span{color:#64748b;display:block;font-size:12px;font-weight:800;text-transform:uppercase}.absolute-voice-proof-trends__metrics strong{display:block;font-size:20px;margin-top:4px}.absolute-voice-proof-trends__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-proof-trends__links a{border:1px solid #99f6e4;border-radius:999px;color:#0f766e;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-proof-trends__error{color:#9f1239;font-weight:700}`;
|
|
@@ -4080,7 +4345,7 @@ var DEFAULT_LINKS3 = [
|
|
|
4080
4345
|
{ href: "/production-readiness", label: "Readiness page" },
|
|
4081
4346
|
{ href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
|
|
4082
4347
|
];
|
|
4083
|
-
var
|
|
4348
|
+
var escapeHtml5 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
4084
4349
|
var formatExplanationValue = (value, unit) => {
|
|
4085
4350
|
if (value === undefined || value === null) {
|
|
4086
4351
|
return "n/a";
|
|
@@ -4121,23 +4386,23 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
|
|
|
4121
4386
|
};
|
|
4122
4387
|
var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
|
|
4123
4388
|
const model = createVoiceReadinessFailuresViewModel(snapshot, options);
|
|
4124
|
-
const failures = model.failures.length ? `<div class="absolute-voice-readiness-failures__items">${model.failures.map((failure) => `<article class="absolute-voice-readiness-failures__item absolute-voice-readiness-failures__item--${
|
|
4125
|
-
<span>${
|
|
4126
|
-
<strong>${
|
|
4127
|
-
<p>Observed ${
|
|
4128
|
-
<p>${
|
|
4129
|
-
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${
|
|
4130
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ?
|
|
4131
|
-
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${
|
|
4132
|
-
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${
|
|
4389
|
+
const failures = model.failures.length ? `<div class="absolute-voice-readiness-failures__items">${model.failures.map((failure) => `<article class="absolute-voice-readiness-failures__item absolute-voice-readiness-failures__item--${escapeHtml5(failure.status)}">
|
|
4390
|
+
<span>${escapeHtml5(failure.status.toUpperCase())}</span>
|
|
4391
|
+
<strong>${escapeHtml5(failure.label)}</strong>
|
|
4392
|
+
<p>Observed ${escapeHtml5(failure.observed)} against ${escapeHtml5(failure.thresholdLabel)} ${escapeHtml5(failure.threshold)}.</p>
|
|
4393
|
+
<p>${escapeHtml5(failure.remediation)}</p>
|
|
4394
|
+
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml5(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml5(failure.sourceHref)}">Threshold source</a>` : ""}</p>
|
|
4395
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml5(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
|
|
4396
|
+
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml5(link.href)}">${escapeHtml5(link.label)}</a>`).join("")}</p>` : "";
|
|
4397
|
+
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml5(model.status)}">
|
|
4133
4398
|
<header class="absolute-voice-readiness-failures__header">
|
|
4134
|
-
<span class="absolute-voice-readiness-failures__eyebrow">${
|
|
4135
|
-
<strong class="absolute-voice-readiness-failures__label">${
|
|
4399
|
+
<span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml5(model.title)}</span>
|
|
4400
|
+
<strong class="absolute-voice-readiness-failures__label">${escapeHtml5(model.label)}</strong>
|
|
4136
4401
|
</header>
|
|
4137
|
-
<p class="absolute-voice-readiness-failures__description">${
|
|
4402
|
+
<p class="absolute-voice-readiness-failures__description">${escapeHtml5(model.description)}</p>
|
|
4138
4403
|
${failures}
|
|
4139
4404
|
${links}
|
|
4140
|
-
${model.error ? `<p class="absolute-voice-readiness-failures__error">${
|
|
4405
|
+
${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml5(model.error)}</p>` : ""}
|
|
4141
4406
|
</section>`;
|
|
4142
4407
|
};
|
|
4143
4408
|
var getVoiceReadinessFailuresCSS = () => `.absolute-voice-readiness-failures{border:1px solid #fed7aa;border-radius:20px;background:#fff7ed;color:#1c1917;padding:18px;box-shadow:0 18px 40px rgba(234,88,12,.12);font-family:inherit}.absolute-voice-readiness-failures--ready{border-color:#86efac;background:#f0fdf4}.absolute-voice-readiness-failures--error{border-color:#fda4af;background:#fff1f2}.absolute-voice-readiness-failures__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-readiness-failures__eyebrow{color:#9a3412;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-readiness-failures__label{font-size:24px;line-height:1}.absolute-voice-readiness-failures__description,.absolute-voice-readiness-failures__empty{color:#57534e}.absolute-voice-readiness-failures__items{display:grid;gap:10px;margin-top:14px}.absolute-voice-readiness-failures__item{background:white;border:1px solid #fed7aa;border-radius:16px;padding:12px}.absolute-voice-readiness-failures__item--fail{border-color:#fb7185}.absolute-voice-readiness-failures__item span{color:#9a3412;display:block;font-size:12px;font-weight:900;text-transform:uppercase}.absolute-voice-readiness-failures__item strong{display:block;font-size:18px;margin-top:4px}.absolute-voice-readiness-failures__item p{margin:.45rem 0 0}.absolute-voice-readiness-failures__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-readiness-failures__links a{border:1px solid #fdba74;border-radius:999px;color:#9a3412;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-readiness-failures__error{color:#9f1239;font-weight:700}`;
|
|
@@ -4179,7 +4444,7 @@ var defineVoiceReadinessFailuresElement = (tagName = "absolute-voice-readiness-f
|
|
|
4179
4444
|
// src/client/opsActionCenterWidget.ts
|
|
4180
4445
|
var DEFAULT_TITLE5 = "Voice Ops Action Center";
|
|
4181
4446
|
var DEFAULT_DESCRIPTION5 = "Run production voice proofs and operator actions from one primitive panel.";
|
|
4182
|
-
var
|
|
4447
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
4183
4448
|
var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
4184
4449
|
const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
|
|
4185
4450
|
return {
|
|
@@ -4201,18 +4466,18 @@ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
|
4201
4466
|
};
|
|
4202
4467
|
var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
|
|
4203
4468
|
const model = createVoiceOpsActionCenterViewModel(snapshot, options);
|
|
4204
|
-
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${
|
|
4205
|
-
${
|
|
4469
|
+
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml6(action.id)}"${action.disabled ? " disabled" : ""}>
|
|
4470
|
+
${escapeHtml6(action.isRunning ? "Working..." : action.label)}
|
|
4206
4471
|
</button>`).join("");
|
|
4207
|
-
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${
|
|
4472
|
+
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml6(model.status)}">
|
|
4208
4473
|
<header class="absolute-voice-ops-action-center__header">
|
|
4209
|
-
<span class="absolute-voice-ops-action-center__eyebrow">${
|
|
4210
|
-
<strong class="absolute-voice-ops-action-center__label">${
|
|
4474
|
+
<span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml6(model.title)}</span>
|
|
4475
|
+
<strong class="absolute-voice-ops-action-center__label">${escapeHtml6(model.label)}</strong>
|
|
4211
4476
|
</header>
|
|
4212
|
-
<p class="absolute-voice-ops-action-center__description">${
|
|
4477
|
+
<p class="absolute-voice-ops-action-center__description">${escapeHtml6(model.description)}</p>
|
|
4213
4478
|
<div class="absolute-voice-ops-action-center__actions">${actions}</div>
|
|
4214
|
-
<p class="absolute-voice-ops-action-center__result">${
|
|
4215
|
-
${model.error ? `<p class="absolute-voice-ops-action-center__error">${
|
|
4479
|
+
<p class="absolute-voice-ops-action-center__result">${escapeHtml6(model.lastResultLabel)}</p>
|
|
4480
|
+
${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml6(model.error)}</p>` : ""}
|
|
4216
4481
|
</section>`;
|
|
4217
4482
|
};
|
|
4218
4483
|
var getVoiceOpsActionCenterCSS = () => `.absolute-voice-ops-action-center{border:1px solid #d5cbb8;border-radius:20px;background:#fffaf1;color:#17130b;padding:18px;box-shadow:0 18px 40px rgba(58,42,16,.12);font-family:inherit}.absolute-voice-ops-action-center--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-ops-action-center__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-ops-action-center__eyebrow{color:#725d37;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-ops-action-center__label{font-size:28px;line-height:1}.absolute-voice-ops-action-center__description,.absolute-voice-ops-action-center__result{color:#5b4b2f;margin:12px 0 0}.absolute-voice-ops-action-center__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-ops-action-center__actions button{background:#7c4a03;border:0;border-radius:999px;color:#fff8e8;cursor:pointer;font:inherit;font-weight:800;padding:8px 12px}.absolute-voice-ops-action-center__actions button:disabled{cursor:not-allowed;opacity:.5}.absolute-voice-ops-action-center__error{color:#9f1239;font-weight:700}`;
|
|
@@ -4813,7 +5078,7 @@ var exportVoiceTrace = async (input) => {
|
|
|
4813
5078
|
};
|
|
4814
5079
|
};
|
|
4815
5080
|
var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
4816
|
-
var
|
|
5081
|
+
var escapeHtml7 = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
4817
5082
|
var formatTraceValue = (value) => {
|
|
4818
5083
|
if (value === undefined || value === null) {
|
|
4819
5084
|
return "";
|
|
@@ -5093,10 +5358,10 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5093
5358
|
const offset = summary.startedAt === undefined ? event.at : Math.max(0, event.at - summary.startedAt);
|
|
5094
5359
|
return [
|
|
5095
5360
|
"<tr>",
|
|
5096
|
-
`<td>${
|
|
5097
|
-
`<td>${
|
|
5098
|
-
`<td>${
|
|
5099
|
-
`<td><code>${
|
|
5361
|
+
`<td>${escapeHtml7(String(offset))}</td>`,
|
|
5362
|
+
`<td>${escapeHtml7(event.type)}</td>`,
|
|
5363
|
+
`<td>${escapeHtml7(event.turnId ?? "")}</td>`,
|
|
5364
|
+
`<td><code>${escapeHtml7(JSON.stringify(event.payload))}</code></td>`,
|
|
5100
5365
|
"</tr>"
|
|
5101
5366
|
].join("");
|
|
5102
5367
|
}).join(`
|
|
@@ -5107,7 +5372,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5107
5372
|
"<head>",
|
|
5108
5373
|
'<meta charset="utf-8" />',
|
|
5109
5374
|
'<meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
5110
|
-
`<title>${
|
|
5375
|
+
`<title>${escapeHtml7(options.title ?? "Voice Trace")}</title>`,
|
|
5111
5376
|
"<style>",
|
|
5112
5377
|
"body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}",
|
|
5113
5378
|
"main{max-width:1100px;margin:auto}",
|
|
@@ -5121,7 +5386,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5121
5386
|
"</style>",
|
|
5122
5387
|
"</head>",
|
|
5123
5388
|
"<body><main>",
|
|
5124
|
-
`<h1>${
|
|
5389
|
+
`<h1>${escapeHtml7(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
|
|
5125
5390
|
`<p class="${evaluation.pass ? "pass" : "fail"}">QA: ${evaluation.pass ? "pass" : "fail"}</p>`,
|
|
5126
5391
|
'<section class="summary">',
|
|
5127
5392
|
`<div class="card"><strong>Events</strong><br>${summary.eventCount}</div>`,
|
|
@@ -5135,7 +5400,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5135
5400
|
eventRows,
|
|
5136
5401
|
"</tbody></table>",
|
|
5137
5402
|
"<h2>Markdown Export</h2>",
|
|
5138
|
-
`<pre>${
|
|
5403
|
+
`<pre>${escapeHtml7(markdown)}</pre>`,
|
|
5139
5404
|
"</main></body></html>"
|
|
5140
5405
|
].join(`
|
|
5141
5406
|
`);
|
|
@@ -5491,7 +5756,7 @@ var ACTION_LABELS = {
|
|
|
5491
5756
|
"resume-assistant": "Resume assistant",
|
|
5492
5757
|
tag: "Tag"
|
|
5493
5758
|
};
|
|
5494
|
-
var
|
|
5759
|
+
var escapeHtml8 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5495
5760
|
var createVoiceLiveOpsInput = (action, input) => ({
|
|
5496
5761
|
action,
|
|
5497
5762
|
assignee: input.assignee,
|
|
@@ -5502,17 +5767,17 @@ var createVoiceLiveOpsInput = (action, input) => ({
|
|
|
5502
5767
|
var renderVoiceLiveOpsHTML = (snapshot, options = {}) => {
|
|
5503
5768
|
const sessionId = options.getSessionId?.() ?? "";
|
|
5504
5769
|
const disabled = snapshot.isRunning || !sessionId;
|
|
5505
|
-
const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${
|
|
5506
|
-
const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${
|
|
5770
|
+
const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${escapeHtml8(action)}"${disabled ? " disabled" : ""}>${escapeHtml8(snapshot.runningAction === action ? "Running..." : ACTION_LABELS[action])}</button>`).join("");
|
|
5771
|
+
const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${escapeHtml8(snapshot.error)}</p>` : snapshot.lastResult ? `<p class="absolute-voice-live-ops__result">Recorded ${escapeHtml8(snapshot.lastResult.action)}. Control: ${escapeHtml8(snapshot.lastResult.control.status)}.</p>` : '<p class="absolute-voice-live-ops__result">No live ops action has run yet.</p>';
|
|
5507
5772
|
return `<section class="absolute-voice-live-ops">
|
|
5508
5773
|
<header class="absolute-voice-live-ops__header">
|
|
5509
|
-
<span>${
|
|
5510
|
-
<strong>${
|
|
5774
|
+
<span>${escapeHtml8(options.title ?? "Live Ops")}</span>
|
|
5775
|
+
<strong>${escapeHtml8(sessionId || "No active session")}</strong>
|
|
5511
5776
|
</header>
|
|
5512
|
-
<p class="absolute-voice-live-ops__description">${
|
|
5513
|
-
<label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${
|
|
5514
|
-
<label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${
|
|
5515
|
-
<label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${
|
|
5777
|
+
<p class="absolute-voice-live-ops__description">${escapeHtml8(options.description ?? "Pause, resume, take over, force handoff, or inject operator instructions during a live voice session.")}</p>
|
|
5778
|
+
<label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${escapeHtml8(options.defaultAssignee ?? "operator")}" /></label>
|
|
5779
|
+
<label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${escapeHtml8(options.defaultTag ?? "live-ops")}" /></label>
|
|
5780
|
+
<label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${escapeHtml8(options.defaultDetail ?? "Operator marked this live session.")}" /></label>
|
|
5516
5781
|
<div class="absolute-voice-live-ops__actions">${actions}</div>
|
|
5517
5782
|
${result}
|
|
5518
5783
|
</section>`;
|
|
@@ -5599,16 +5864,16 @@ var defineVoiceLiveOpsElement = (tagName = "absolute-voice-live-ops", options =
|
|
|
5599
5864
|
});
|
|
5600
5865
|
};
|
|
5601
5866
|
// src/client/opsActionHistoryWidget.ts
|
|
5602
|
-
var
|
|
5867
|
+
var escapeHtml9 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5603
5868
|
var renderVoiceOpsActionHistoryWidgetHTML = (snapshot, options = {}) => {
|
|
5604
5869
|
const report = snapshot.report;
|
|
5605
5870
|
const entries = (report?.entries ?? []).slice(0, options.limit ?? 5);
|
|
5606
|
-
const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${
|
|
5871
|
+
const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${escapeHtml9(entry.actionId)}</span><strong>${escapeHtml9(entry.ok ? "Success" : "Failed")}</strong><small>${escapeHtml9(new Date(entry.at).toLocaleString())}${entry.status ? ` \xB7 HTTP ${String(entry.status)}` : ""}</small></li>`).join("");
|
|
5607
5872
|
return `<section class="absolute-voice-ops-action-history">
|
|
5608
|
-
<header><span>Operator proof</span><strong>${
|
|
5873
|
+
<header><span>Operator proof</span><strong>${escapeHtml9(options.title ?? "Action History")}</strong></header>
|
|
5609
5874
|
<p>${String(report?.total ?? 0)} action(s), ${String(report?.failed ?? 0)} failed.</p>
|
|
5610
5875
|
<ul>${rows || "<li>No operator actions recorded yet.</li>"}</ul>
|
|
5611
|
-
${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${
|
|
5876
|
+
${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${escapeHtml9(snapshot.error)}</p>` : ""}
|
|
5612
5877
|
</section>`;
|
|
5613
5878
|
};
|
|
5614
5879
|
var getVoiceOpsActionHistoryCSS = () => `.absolute-voice-ops-action-history{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;font-family:inherit}.absolute-voice-ops-action-history header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-ops-action-history header span{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-ops-action-history header strong{font-size:24px}.absolute-voice-ops-action-history p{color:#514733}.absolute-voice-ops-action-history ul{display:grid;gap:8px;list-style:none;margin:12px 0 0;padding:0}.absolute-voice-ops-action-history__entry{background:#fff;border:1px solid #eee4d2;border-radius:14px;display:grid;gap:3px;padding:10px 12px}.absolute-voice-ops-action-history__entry--error{border-color:#f2a7a7}.absolute-voice-ops-action-history__entry span{font-weight:800}.absolute-voice-ops-action-history__entry small{color:#655944}.absolute-voice-ops-action-history__error{color:#9f1239;font-weight:700}`;
|
|
@@ -5631,7 +5896,7 @@ var mountVoiceOpsActionHistory = (element, path = "/api/voice/ops-actions/histor
|
|
|
5631
5896
|
// src/client/deliveryRuntimeWidget.ts
|
|
5632
5897
|
var DEFAULT_TITLE6 = "Voice Delivery Runtime";
|
|
5633
5898
|
var DEFAULT_DESCRIPTION6 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
|
|
5634
|
-
var
|
|
5899
|
+
var escapeHtml10 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5635
5900
|
var createSurface = (id, summary) => {
|
|
5636
5901
|
if (!summary) {
|
|
5637
5902
|
return {
|
|
@@ -5680,26 +5945,26 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
|
|
|
5680
5945
|
};
|
|
5681
5946
|
var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
|
|
5682
5947
|
const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
|
|
5683
|
-
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${
|
|
5684
|
-
<span>${
|
|
5685
|
-
<strong>${
|
|
5948
|
+
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml10(surface.status)}">
|
|
5949
|
+
<span>${escapeHtml10(surface.label)}</span>
|
|
5950
|
+
<strong>${escapeHtml10(surface.detail)}</strong>
|
|
5686
5951
|
<small>${String(surface.failed)} failed · ${String(surface.deadLettered)} dead-lettered</small>
|
|
5687
5952
|
</li>`).join("");
|
|
5688
5953
|
const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
|
|
5689
5954
|
<button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
|
|
5690
5955
|
<button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
|
|
5691
5956
|
</div>`;
|
|
5692
|
-
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
5693
|
-
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${
|
|
5957
|
+
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml10(model.actionError)}</p>` : "";
|
|
5958
|
+
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml10(model.status)}">
|
|
5694
5959
|
<header class="absolute-voice-delivery-runtime__header">
|
|
5695
|
-
<span class="absolute-voice-delivery-runtime__eyebrow">${
|
|
5696
|
-
<strong class="absolute-voice-delivery-runtime__label">${
|
|
5960
|
+
<span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml10(model.title)}</span>
|
|
5961
|
+
<strong class="absolute-voice-delivery-runtime__label">${escapeHtml10(model.label)}</strong>
|
|
5697
5962
|
</header>
|
|
5698
|
-
<p class="absolute-voice-delivery-runtime__description">${
|
|
5963
|
+
<p class="absolute-voice-delivery-runtime__description">${escapeHtml10(model.description)}</p>
|
|
5699
5964
|
<ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
|
|
5700
5965
|
${actions}
|
|
5701
5966
|
${actionError}
|
|
5702
|
-
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
5967
|
+
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml10(model.error)}</p>` : ""}
|
|
5703
5968
|
</section>`;
|
|
5704
5969
|
};
|
|
5705
5970
|
var getVoiceDeliveryRuntimeCSS = () => `.absolute-voice-delivery-runtime{border:1px solid #c9d8cf;border-radius:20px;background:#f6fff9;color:#0d1b12;padding:18px;box-shadow:0 18px 40px rgba(19,55,35,.12);font-family:inherit}.absolute-voice-delivery-runtime--warn,.absolute-voice-delivery-runtime--error{border-color:#f2b56b;background:#fff9ed}.absolute-voice-delivery-runtime__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-delivery-runtime__eyebrow{color:#4e6b59;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-delivery-runtime__label{font-size:28px;line-height:1}.absolute-voice-delivery-runtime__description{color:#33483b;margin:12px 0 0}.absolute-voice-delivery-runtime__surfaces{display:grid;gap:8px;list-style:none;margin:16px 0 0;padding:0}.absolute-voice-delivery-runtime__surface{background:#fff;border:1px solid #d9eadf;border-radius:14px;display:grid;gap:4px;padding:10px 12px}.absolute-voice-delivery-runtime__surface--warn{border-color:#f2b56b}.absolute-voice-delivery-runtime__surface--disabled{opacity:.72}.absolute-voice-delivery-runtime__surface span,.absolute-voice-delivery-runtime__surface small{color:#587063}.absolute-voice-delivery-runtime__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-delivery-runtime__actions button{background:#134e2d;border:0;border-radius:999px;color:#f6fff9;cursor:pointer;font:inherit;font-weight:800;padding:8px 12px}.absolute-voice-delivery-runtime__actions button:disabled{cursor:not-allowed;opacity:.48}.absolute-voice-delivery-runtime__error{color:#9f1239;font-weight:700}`;
|
|
@@ -5837,7 +6102,7 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
5837
6102
|
// src/client/routingStatusWidget.ts
|
|
5838
6103
|
var DEFAULT_TITLE7 = "Voice Routing";
|
|
5839
6104
|
var DEFAULT_DESCRIPTION7 = "Latest provider routing decision from the self-hosted trace store.";
|
|
5840
|
-
var
|
|
6105
|
+
var escapeHtml11 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5841
6106
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
5842
6107
|
var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
5843
6108
|
const decision = snapshot.decision;
|
|
@@ -5874,17 +6139,17 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
5874
6139
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
5875
6140
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
5876
6141
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
5877
|
-
<span>${
|
|
5878
|
-
<strong>${
|
|
6142
|
+
<span>${escapeHtml11(row.label)}</span>
|
|
6143
|
+
<strong>${escapeHtml11(row.value)}</strong>
|
|
5879
6144
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
5880
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
6145
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml11(model.status)}">
|
|
5881
6146
|
<header class="absolute-voice-routing-status__header">
|
|
5882
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
5883
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
6147
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml11(model.title)}</span>
|
|
6148
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml11(model.label)}</strong>
|
|
5884
6149
|
</header>
|
|
5885
|
-
<p class="absolute-voice-routing-status__description">${
|
|
6150
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml11(model.description)}</p>
|
|
5886
6151
|
${rows}
|
|
5887
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
6152
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml11(model.error)}</p>` : ""}
|
|
5888
6153
|
</section>`;
|
|
5889
6154
|
};
|
|
5890
6155
|
var getVoiceRoutingStatusCSS = () => `.absolute-voice-routing-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-routing-status--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-routing-status__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-routing-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-routing-status__label{font-size:24px;line-height:1}.absolute-voice-routing-status__description{color:#514733;margin:12px 0 0}.absolute-voice-routing-status__grid{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:14px}.absolute-voice-routing-status__grid div{background:#fff;border:1px solid #eee4d2;border-radius:14px;padding:10px 12px}.absolute-voice-routing-status__grid span{color:#655944;display:block;font-size:12px;margin-bottom:4px}.absolute-voice-routing-status__grid strong{overflow-wrap:anywhere}.absolute-voice-routing-status__empty{color:#655944;margin:14px 0 0}.absolute-voice-routing-status__error{color:#9f1239;font-weight:700}`;
|
|
@@ -6683,7 +6948,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
6683
6948
|
};
|
|
6684
6949
|
};
|
|
6685
6950
|
// src/client/providerSimulationControlsWidget.ts
|
|
6686
|
-
var
|
|
6951
|
+
var escapeHtml12 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6687
6952
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
6688
6953
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
6689
6954
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -6703,18 +6968,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
6703
6968
|
};
|
|
6704
6969
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
6705
6970
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
6706
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
6707
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
6971
|
+
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml12(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml12(provider.provider)} ${escapeHtml12(formatKind(options.kind))} failure</button>`).join("");
|
|
6972
|
+
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml12(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml12(provider.provider)} recovered</button>`).join("");
|
|
6708
6973
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
6709
6974
|
<header class="absolute-voice-provider-simulation__header">
|
|
6710
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
6711
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
6975
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml12(model.title)}</span>
|
|
6976
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml12(model.label)}</strong>
|
|
6712
6977
|
</header>
|
|
6713
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
6714
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
6978
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml12(model.description)}</p>
|
|
6979
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml12(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
6715
6980
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
6716
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
6717
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
6981
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml12(snapshot.error)}</p>` : ""}
|
|
6982
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml12(model.resultText)}</pre>` : ""}
|
|
6718
6983
|
</section>`;
|
|
6719
6984
|
};
|
|
6720
6985
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -6781,7 +7046,7 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
|
|
|
6781
7046
|
// src/client/providerStatusWidget.ts
|
|
6782
7047
|
var DEFAULT_TITLE8 = "Voice Providers";
|
|
6783
7048
|
var DEFAULT_DESCRIPTION8 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
6784
|
-
var
|
|
7049
|
+
var escapeHtml13 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6785
7050
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
6786
7051
|
var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
6787
7052
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -6837,25 +7102,25 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
6837
7102
|
};
|
|
6838
7103
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
6839
7104
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
6840
|
-
const providers = model.providers.length ? `<div class="absolute-voice-provider-status__providers">${model.providers.map((provider) => `<article class="absolute-voice-provider-status__provider absolute-voice-provider-status__provider--${
|
|
7105
|
+
const providers = model.providers.length ? `<div class="absolute-voice-provider-status__providers">${model.providers.map((provider) => `<article class="absolute-voice-provider-status__provider absolute-voice-provider-status__provider--${escapeHtml13(provider.status)}">
|
|
6841
7106
|
<header>
|
|
6842
|
-
<strong>${
|
|
6843
|
-
<span>${
|
|
7107
|
+
<strong>${escapeHtml13(provider.label)}</strong>
|
|
7108
|
+
<span>${escapeHtml13(formatStatus2(provider.status))}</span>
|
|
6844
7109
|
</header>
|
|
6845
|
-
<p>${
|
|
7110
|
+
<p>${escapeHtml13(provider.detail)}</p>
|
|
6846
7111
|
<dl>${provider.rows.map((row) => `<div>
|
|
6847
|
-
<dt>${
|
|
6848
|
-
<dd>${
|
|
7112
|
+
<dt>${escapeHtml13(row.label)}</dt>
|
|
7113
|
+
<dd>${escapeHtml13(row.value)}</dd>
|
|
6849
7114
|
</div>`).join("")}</dl>
|
|
6850
7115
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
6851
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
7116
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml13(model.status)}">
|
|
6852
7117
|
<header class="absolute-voice-provider-status__header">
|
|
6853
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
6854
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
7118
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml13(model.title)}</span>
|
|
7119
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml13(model.label)}</strong>
|
|
6855
7120
|
</header>
|
|
6856
|
-
<p class="absolute-voice-provider-status__description">${
|
|
7121
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml13(model.description)}</p>
|
|
6857
7122
|
${providers}
|
|
6858
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
7123
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml13(model.error)}</p>` : ""}
|
|
6859
7124
|
</section>`;
|
|
6860
7125
|
};
|
|
6861
7126
|
var getVoiceProviderStatusCSS = () => `.absolute-voice-provider-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-provider-status--error,.absolute-voice-provider-status--warning{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-provider-status__header,.absolute-voice-provider-status__provider header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-status__label{font-size:24px;line-height:1}.absolute-voice-provider-status__description,.absolute-voice-provider-status__provider p,.absolute-voice-provider-status__provider dt,.absolute-voice-provider-status__empty{color:#514733}.absolute-voice-provider-status__providers{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-status__provider{background:#fff;border:1px solid #eee4d2;border-radius:16px;padding:14px}.absolute-voice-provider-status__provider--degraded,.absolute-voice-provider-status__provider--rate-limited,.absolute-voice-provider-status__provider--suppressed{border-color:#f2a7a7}.absolute-voice-provider-status__provider--recoverable{border-color:#fbbf24}.absolute-voice-provider-status__provider p{margin:10px 0}.absolute-voice-provider-status__provider dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-status__provider div{background:#fffaf0;border:1px solid #eee4d2;border-radius:12px;padding:8px}.absolute-voice-provider-status__provider dt{font-size:12px}.absolute-voice-provider-status__provider dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-status__empty{margin:14px 0 0}.absolute-voice-provider-status__error{color:#9f1239;font-weight:700}`;
|
|
@@ -6898,7 +7163,7 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
|
|
|
6898
7163
|
// src/client/providerCapabilitiesWidget.ts
|
|
6899
7164
|
var DEFAULT_TITLE9 = "Provider Capabilities";
|
|
6900
7165
|
var DEFAULT_DESCRIPTION9 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
6901
|
-
var
|
|
7166
|
+
var escapeHtml14 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6902
7167
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
6903
7168
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
6904
7169
|
var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
@@ -6953,25 +7218,25 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
6953
7218
|
};
|
|
6954
7219
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
6955
7220
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
6956
|
-
const capabilities = model.capabilities.length ? `<div class="absolute-voice-provider-capabilities__providers">${model.capabilities.map((capability) => `<article class="absolute-voice-provider-capabilities__provider absolute-voice-provider-capabilities__provider--${
|
|
7221
|
+
const capabilities = model.capabilities.length ? `<div class="absolute-voice-provider-capabilities__providers">${model.capabilities.map((capability) => `<article class="absolute-voice-provider-capabilities__provider absolute-voice-provider-capabilities__provider--${escapeHtml14(capability.status)}">
|
|
6957
7222
|
<header>
|
|
6958
|
-
<strong>${
|
|
6959
|
-
<span>${
|
|
7223
|
+
<strong>${escapeHtml14(capability.label)}</strong>
|
|
7224
|
+
<span>${escapeHtml14(formatStatus3(capability.status))}</span>
|
|
6960
7225
|
</header>
|
|
6961
|
-
<p>${
|
|
7226
|
+
<p>${escapeHtml14(capability.detail)}</p>
|
|
6962
7227
|
<dl>${capability.rows.map((row) => `<div>
|
|
6963
|
-
<dt>${
|
|
6964
|
-
<dd>${
|
|
7228
|
+
<dt>${escapeHtml14(row.label)}</dt>
|
|
7229
|
+
<dd>${escapeHtml14(row.value)}</dd>
|
|
6965
7230
|
</div>`).join("")}</dl>
|
|
6966
7231
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
|
|
6967
|
-
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${
|
|
7232
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml14(model.status)}">
|
|
6968
7233
|
<header class="absolute-voice-provider-capabilities__header">
|
|
6969
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
6970
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
7234
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml14(model.title)}</span>
|
|
7235
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml14(model.label)}</strong>
|
|
6971
7236
|
</header>
|
|
6972
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
7237
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml14(model.description)}</p>
|
|
6973
7238
|
${capabilities}
|
|
6974
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
7239
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml14(model.error)}</p>` : ""}
|
|
6975
7240
|
</section>`;
|
|
6976
7241
|
};
|
|
6977
7242
|
var getVoiceProviderCapabilitiesCSS = () => `.absolute-voice-provider-capabilities{border:1px solid #bfd7ea;border-radius:20px;background:#f6fbff;color:#08131f;padding:18px;box-shadow:0 18px 40px rgba(14,51,78,.12);font-family:inherit}.absolute-voice-provider-capabilities--error,.absolute-voice-provider-capabilities--warning{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-provider-capabilities__header,.absolute-voice-provider-capabilities__provider header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-capabilities__eyebrow{color:#255f85;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-capabilities__label{font-size:24px;line-height:1}.absolute-voice-provider-capabilities__description,.absolute-voice-provider-capabilities__provider p,.absolute-voice-provider-capabilities__provider dt,.absolute-voice-provider-capabilities__empty{color:#405467}.absolute-voice-provider-capabilities__providers{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-capabilities__provider{background:#fff;border:1px solid #d7e7f3;border-radius:16px;padding:14px}.absolute-voice-provider-capabilities__provider--selected,.absolute-voice-provider-capabilities__provider--healthy{border-color:#86efac}.absolute-voice-provider-capabilities__provider--degraded,.absolute-voice-provider-capabilities__provider--rate-limited,.absolute-voice-provider-capabilities__provider--suppressed,.absolute-voice-provider-capabilities__provider--unconfigured{border-color:#f2a7a7}.absolute-voice-provider-capabilities__provider p{margin:10px 0}.absolute-voice-provider-capabilities__provider dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-capabilities__provider div{background:#f6fbff;border:1px solid #d7e7f3;border-radius:12px;padding:8px}.absolute-voice-provider-capabilities__provider dt{font-size:12px}.absolute-voice-provider-capabilities__provider dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-capabilities__empty{margin:14px 0 0}.absolute-voice-provider-capabilities__error{color:#9f1239;font-weight:700}`;
|
|
@@ -7014,7 +7279,7 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
|
|
|
7014
7279
|
// src/client/providerContractsWidget.ts
|
|
7015
7280
|
var DEFAULT_TITLE10 = "Provider Contracts";
|
|
7016
7281
|
var DEFAULT_DESCRIPTION10 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
|
|
7017
|
-
var
|
|
7282
|
+
var escapeHtml15 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7018
7283
|
var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
7019
7284
|
var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
7020
7285
|
var contractDetail = (row) => {
|
|
@@ -7058,26 +7323,26 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
|
|
|
7058
7323
|
};
|
|
7059
7324
|
var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
|
|
7060
7325
|
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
7061
|
-
const rows = model.rows.length ? `<div class="absolute-voice-provider-contracts__rows">${model.rows.map((row) => `<article class="absolute-voice-provider-contracts__row absolute-voice-provider-contracts__row--${
|
|
7326
|
+
const rows = model.rows.length ? `<div class="absolute-voice-provider-contracts__rows">${model.rows.map((row) => `<article class="absolute-voice-provider-contracts__row absolute-voice-provider-contracts__row--${escapeHtml15(row.status)}">
|
|
7062
7327
|
<header>
|
|
7063
|
-
<strong>${
|
|
7064
|
-
<span>${
|
|
7328
|
+
<strong>${escapeHtml15(row.label)}</strong>
|
|
7329
|
+
<span>${escapeHtml15(formatStatus4(row.status))}</span>
|
|
7065
7330
|
</header>
|
|
7066
|
-
<p>${
|
|
7067
|
-
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${
|
|
7331
|
+
<p>${escapeHtml15(row.detail)}</p>
|
|
7332
|
+
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml15(remediation.href)}">${escapeHtml15(remediation.label)}</a>` : `<strong>${escapeHtml15(remediation.label)}</strong>`}<span>${escapeHtml15(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
|
|
7068
7333
|
<dl>${row.rows.map((item) => `<div>
|
|
7069
|
-
<dt>${
|
|
7070
|
-
<dd>${
|
|
7334
|
+
<dt>${escapeHtml15(item.label)}</dt>
|
|
7335
|
+
<dd>${escapeHtml15(item.value)}</dd>
|
|
7071
7336
|
</div>`).join("")}</dl>
|
|
7072
7337
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
|
|
7073
|
-
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${
|
|
7338
|
+
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml15(model.status)}">
|
|
7074
7339
|
<header class="absolute-voice-provider-contracts__header">
|
|
7075
|
-
<span class="absolute-voice-provider-contracts__eyebrow">${
|
|
7076
|
-
<strong class="absolute-voice-provider-contracts__label">${
|
|
7340
|
+
<span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml15(model.title)}</span>
|
|
7341
|
+
<strong class="absolute-voice-provider-contracts__label">${escapeHtml15(model.label)}</strong>
|
|
7077
7342
|
</header>
|
|
7078
|
-
<p class="absolute-voice-provider-contracts__description">${
|
|
7343
|
+
<p class="absolute-voice-provider-contracts__description">${escapeHtml15(model.description)}</p>
|
|
7079
7344
|
${rows}
|
|
7080
|
-
${model.error ? `<p class="absolute-voice-provider-contracts__error">${
|
|
7345
|
+
${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml15(model.error)}</p>` : ""}
|
|
7081
7346
|
</section>`;
|
|
7082
7347
|
};
|
|
7083
7348
|
var getVoiceProviderContractsCSS = () => `.absolute-voice-provider-contracts{border:1px solid #b8dcc7;border-radius:20px;background:#f7fff9;color:#09140d;padding:18px;box-shadow:0 18px 40px rgba(21,83,45,.12);font-family:inherit}.absolute-voice-provider-contracts--error,.absolute-voice-provider-contracts--warning{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-provider-contracts__header,.absolute-voice-provider-contracts__row header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-contracts__eyebrow{color:#166534;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-contracts__label{font-size:24px;line-height:1}.absolute-voice-provider-contracts__description,.absolute-voice-provider-contracts__row p,.absolute-voice-provider-contracts__row dt,.absolute-voice-provider-contracts__empty{color:#405448}.absolute-voice-provider-contracts__rows{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-contracts__row{background:#fff;border:1px solid #d6eadb;border-radius:16px;padding:14px}.absolute-voice-provider-contracts__row--pass{border-color:#86efac}.absolute-voice-provider-contracts__row--warn,.absolute-voice-provider-contracts__row--fail{border-color:#f2a7a7}.absolute-voice-provider-contracts__row p{margin:10px 0}.absolute-voice-provider-contracts__remediations{display:grid;gap:8px;list-style:none;margin:0 0 10px;padding:0}.absolute-voice-provider-contracts__remediations li{background:#fff7ed;border:1px solid #fed7aa;border-radius:12px;display:grid;gap:3px;padding:8px}.absolute-voice-provider-contracts__remediations a,.absolute-voice-provider-contracts__remediations strong{color:#9a3412}.absolute-voice-provider-contracts__remediations span{color:#7c2d12}.absolute-voice-provider-contracts__row dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-contracts__row div{background:#f7fff9;border:1px solid #d6eadb;border-radius:12px;padding:8px}.absolute-voice-provider-contracts__row dt{font-size:12px}.absolute-voice-provider-contracts__row dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-contracts__error{color:#9f1239;font-weight:700}`;
|
|
@@ -7120,7 +7385,7 @@ var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-co
|
|
|
7120
7385
|
// src/client/turnQualityWidget.ts
|
|
7121
7386
|
var DEFAULT_TITLE11 = "Turn Quality";
|
|
7122
7387
|
var DEFAULT_DESCRIPTION11 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
7123
|
-
var
|
|
7388
|
+
var escapeHtml16 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7124
7389
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
7125
7390
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
7126
7391
|
var getTurnDetail = (turn) => {
|
|
@@ -7170,25 +7435,25 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
7170
7435
|
};
|
|
7171
7436
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
7172
7437
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
7173
|
-
const turns = model.turns.length ? `<div class="absolute-voice-turn-quality__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-quality__turn absolute-voice-turn-quality__turn--${
|
|
7438
|
+
const turns = model.turns.length ? `<div class="absolute-voice-turn-quality__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-quality__turn absolute-voice-turn-quality__turn--${escapeHtml16(turn.status)}">
|
|
7174
7439
|
<header>
|
|
7175
|
-
<strong>${
|
|
7176
|
-
<span>${
|
|
7440
|
+
<strong>${escapeHtml16(turn.label)}</strong>
|
|
7441
|
+
<span>${escapeHtml16(turn.status)}</span>
|
|
7177
7442
|
</header>
|
|
7178
|
-
<p>${
|
|
7443
|
+
<p>${escapeHtml16(turn.detail)}</p>
|
|
7179
7444
|
<dl>${turn.rows.map((row) => `<div>
|
|
7180
|
-
<dt>${
|
|
7181
|
-
<dd>${
|
|
7445
|
+
<dt>${escapeHtml16(row.label)}</dt>
|
|
7446
|
+
<dd>${escapeHtml16(row.value)}</dd>
|
|
7182
7447
|
</div>`).join("")}</dl>
|
|
7183
7448
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
7184
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
7449
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml16(model.status)}">
|
|
7185
7450
|
<header class="absolute-voice-turn-quality__header">
|
|
7186
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
7187
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
7451
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml16(model.title)}</span>
|
|
7452
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml16(model.label)}</strong>
|
|
7188
7453
|
</header>
|
|
7189
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
7454
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml16(model.description)}</p>
|
|
7190
7455
|
${turns}
|
|
7191
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
7456
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml16(model.error)}</p>` : ""}
|
|
7192
7457
|
</section>`;
|
|
7193
7458
|
};
|
|
7194
7459
|
var getVoiceTurnQualityCSS = () => `.absolute-voice-turn-quality{border:1px solid #e4d1a3;border-radius:20px;background:#fff9eb;color:#17120a;padding:18px;box-shadow:0 18px 40px rgba(73,48,14,.12);font-family:inherit}.absolute-voice-turn-quality--error,.absolute-voice-turn-quality--warning{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-turn-quality__header,.absolute-voice-turn-quality__turn header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-turn-quality__eyebrow{color:#8a5a0a;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-turn-quality__label{font-size:24px;line-height:1}.absolute-voice-turn-quality__description,.absolute-voice-turn-quality__turn p,.absolute-voice-turn-quality__turn dt,.absolute-voice-turn-quality__empty{color:#5a4930}.absolute-voice-turn-quality__turns{display:grid;gap:12px;margin-top:14px}.absolute-voice-turn-quality__turn{background:#fff;border:1px solid #f0dfba;border-radius:16px;padding:14px}.absolute-voice-turn-quality__turn--pass{border-color:#86efac}.absolute-voice-turn-quality__turn--warn,.absolute-voice-turn-quality__turn--unknown{border-color:#fbbf24}.absolute-voice-turn-quality__turn--fail{border-color:#f2a7a7}.absolute-voice-turn-quality__turn p{margin:10px 0}.absolute-voice-turn-quality__turn dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-turn-quality__turn div{background:#fff9eb;border:1px solid #f0dfba;border-radius:12px;padding:8px}.absolute-voice-turn-quality__turn dt{font-size:12px}.absolute-voice-turn-quality__turn dd{font-weight:800;margin:4px 0 0}.absolute-voice-turn-quality__empty{margin:14px 0 0}.absolute-voice-turn-quality__error{color:#9f1239;font-weight:700}`;
|
|
@@ -7232,7 +7497,7 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
|
|
|
7232
7497
|
var DEFAULT_TITLE12 = "Turn Latency";
|
|
7233
7498
|
var DEFAULT_DESCRIPTION12 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
7234
7499
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
7235
|
-
var
|
|
7500
|
+
var escapeHtml17 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7236
7501
|
var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
7237
7502
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
7238
7503
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
@@ -7260,25 +7525,25 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
|
7260
7525
|
};
|
|
7261
7526
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
7262
7527
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
7263
|
-
const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${
|
|
7528
|
+
const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${escapeHtml17(turn.status)}">
|
|
7264
7529
|
<header>
|
|
7265
|
-
<strong>${
|
|
7266
|
-
<span>${
|
|
7530
|
+
<strong>${escapeHtml17(turn.label)}</strong>
|
|
7531
|
+
<span>${escapeHtml17(turn.status)}</span>
|
|
7267
7532
|
</header>
|
|
7268
7533
|
<dl>${turn.rows.map((row) => `<div>
|
|
7269
|
-
<dt>${
|
|
7270
|
-
<dd>${
|
|
7534
|
+
<dt>${escapeHtml17(row.label)}</dt>
|
|
7535
|
+
<dd>${escapeHtml17(row.value)}</dd>
|
|
7271
7536
|
</div>`).join("")}</dl>
|
|
7272
7537
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
7273
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
7538
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml17(model.status)}">
|
|
7274
7539
|
<header class="absolute-voice-turn-latency__header">
|
|
7275
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
7276
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
7540
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml17(model.title)}</span>
|
|
7541
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml17(model.label)}</strong>
|
|
7277
7542
|
</header>
|
|
7278
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
7279
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
7543
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml17(model.description)}</p>
|
|
7544
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml17(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
7280
7545
|
${turns}
|
|
7281
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
7546
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml17(model.error)}</p>` : ""}
|
|
7282
7547
|
</section>`;
|
|
7283
7548
|
};
|
|
7284
7549
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -7330,7 +7595,7 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
|
|
|
7330
7595
|
// src/client/traceTimelineWidget.ts
|
|
7331
7596
|
var DEFAULT_TITLE13 = "Voice Traces";
|
|
7332
7597
|
var DEFAULT_DESCRIPTION13 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
7333
|
-
var
|
|
7598
|
+
var escapeHtml18 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7334
7599
|
var formatMs3 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
7335
7600
|
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
7336
7601
|
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
@@ -7360,27 +7625,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
|
7360
7625
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
7361
7626
|
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
|
|
7362
7627
|
const supportLinks = [
|
|
7363
|
-
`<a href="${
|
|
7364
|
-
session.operationsRecordHref ? `<a href="${
|
|
7365
|
-
session.incidentBundleHref ? `<a href="${
|
|
7628
|
+
`<a href="${escapeHtml18(session.detailHref)}">Open timeline</a>`,
|
|
7629
|
+
session.operationsRecordHref ? `<a href="${escapeHtml18(session.operationsRecordHref)}">Open operations record</a>` : undefined,
|
|
7630
|
+
session.incidentBundleHref ? `<a href="${escapeHtml18(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
|
|
7366
7631
|
].filter(Boolean).join("");
|
|
7367
|
-
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${
|
|
7632
|
+
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml18(session.status)}">
|
|
7368
7633
|
<header>
|
|
7369
|
-
<strong>${
|
|
7370
|
-
<span>${
|
|
7634
|
+
<strong>${escapeHtml18(session.sessionId)}</strong>
|
|
7635
|
+
<span>${escapeHtml18(session.status)}</span>
|
|
7371
7636
|
</header>
|
|
7372
|
-
<p>${
|
|
7637
|
+
<p>${escapeHtml18(session.label)} \xB7 ${escapeHtml18(session.durationLabel)} \xB7 ${escapeHtml18(session.providerLabel)}</p>
|
|
7373
7638
|
<p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
|
|
7374
7639
|
</article>`;
|
|
7375
7640
|
}).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
|
|
7376
|
-
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${
|
|
7641
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml18(model.status)}">
|
|
7377
7642
|
<header class="absolute-voice-trace-timeline__header">
|
|
7378
|
-
<span class="absolute-voice-trace-timeline__eyebrow">${
|
|
7379
|
-
<strong class="absolute-voice-trace-timeline__label">${
|
|
7643
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml18(model.title)}</span>
|
|
7644
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml18(model.label)}</strong>
|
|
7380
7645
|
</header>
|
|
7381
|
-
<p class="absolute-voice-trace-timeline__description">${
|
|
7646
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml18(model.description)}</p>
|
|
7382
7647
|
${sessions}
|
|
7383
|
-
${model.error ? `<p class="absolute-voice-trace-timeline__error">${
|
|
7648
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml18(model.error)}</p>` : ""}
|
|
7384
7649
|
</section>`;
|
|
7385
7650
|
};
|
|
7386
7651
|
var getVoiceTraceTimelineCSS = () => `.absolute-voice-trace-timeline{border:1px solid #bad7d3;border-radius:20px;background:#f3fffb;color:#09201c;padding:18px;box-shadow:0 18px 40px rgba(9,32,28,.12);font-family:inherit}.absolute-voice-trace-timeline--error,.absolute-voice-trace-timeline--failed{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-trace-timeline--warning{border-color:#fbbf24;background:#fffaf0}.absolute-voice-trace-timeline__header,.absolute-voice-trace-timeline__session header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-trace-timeline__eyebrow{color:#17665b;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-trace-timeline__label{font-size:24px;line-height:1}.absolute-voice-trace-timeline__description,.absolute-voice-trace-timeline__session p,.absolute-voice-trace-timeline__empty{color:#35544f}.absolute-voice-trace-timeline__sessions{display:grid;gap:12px;margin-top:14px}.absolute-voice-trace-timeline__session{background:#fff;border:1px solid #cfe7e2;border-radius:16px;padding:14px}.absolute-voice-trace-timeline__session--failed{border-color:#f2a7a7}.absolute-voice-trace-timeline__session--warning{border-color:#fbbf24}.absolute-voice-trace-timeline__session p{margin:10px 0}.absolute-voice-trace-timeline__actions{display:flex;flex-wrap:wrap;gap:10px}.absolute-voice-trace-timeline__session a{color:#0f766e;font-weight:800}.absolute-voice-trace-timeline__empty{margin:14px 0 0}.absolute-voice-trace-timeline__error{color:#9f1239;font-weight:700}`;
|
|
@@ -7428,7 +7693,7 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
|
|
|
7428
7693
|
// src/client/agentSquadStatusWidget.ts
|
|
7429
7694
|
var DEFAULT_TITLE14 = "Voice Agent Squad";
|
|
7430
7695
|
var DEFAULT_DESCRIPTION14 = "Current specialist and recent handoffs from your self-hosted voice traces.";
|
|
7431
|
-
var
|
|
7696
|
+
var escapeHtml19 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7432
7697
|
var labelFor = (current) => {
|
|
7433
7698
|
if (!current)
|
|
7434
7699
|
return "Waiting for specialist activity";
|
|
@@ -7455,24 +7720,24 @@ var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
|
|
|
7455
7720
|
const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
|
|
7456
7721
|
const current = model.current;
|
|
7457
7722
|
const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
|
|
7458
|
-
<span>${
|
|
7459
|
-
<strong>${
|
|
7460
|
-
<em>${
|
|
7461
|
-
${session.summary || session.reason ? `<p>${
|
|
7723
|
+
<span>${escapeHtml19(session.sessionId)}</span>
|
|
7724
|
+
<strong>${escapeHtml19(session.targetAgentId ?? "none")}</strong>
|
|
7725
|
+
<em>${escapeHtml19(session.status)}</em>
|
|
7726
|
+
${session.summary || session.reason ? `<p>${escapeHtml19(session.summary ?? session.reason ?? "")}</p>` : ""}
|
|
7462
7727
|
</li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
|
|
7463
7728
|
return `<section class="absolute-voice-agent-squad-status">
|
|
7464
7729
|
<header>
|
|
7465
|
-
<span>${
|
|
7466
|
-
<strong>${
|
|
7730
|
+
<span>${escapeHtml19(model.title)}</span>
|
|
7731
|
+
<strong>${escapeHtml19(model.label)}</strong>
|
|
7467
7732
|
</header>
|
|
7468
|
-
<p>${
|
|
7733
|
+
<p>${escapeHtml19(model.description)}</p>
|
|
7469
7734
|
<div>
|
|
7470
|
-
<span>Session</span><strong>${
|
|
7471
|
-
<span>From</span><strong>${
|
|
7472
|
-
<span>Status</span><strong>${
|
|
7735
|
+
<span>Session</span><strong>${escapeHtml19(current?.sessionId ?? "n/a")}</strong>
|
|
7736
|
+
<span>From</span><strong>${escapeHtml19(current?.fromAgentId ?? "n/a")}</strong>
|
|
7737
|
+
<span>Status</span><strong>${escapeHtml19(current?.status ?? "idle")}</strong>
|
|
7473
7738
|
</div>
|
|
7474
7739
|
<ul>${rows}</ul>
|
|
7475
|
-
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${
|
|
7740
|
+
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml19(model.error)}</p>` : ""}
|
|
7476
7741
|
</section>`;
|
|
7477
7742
|
};
|
|
7478
7743
|
var getVoiceAgentSquadStatusCSS = () => `.absolute-voice-agent-squad-status{border:1px solid #38bdf866;border-radius:20px;background:#0f172a;color:#f8fafc;padding:18px;font-family:inherit}.absolute-voice-agent-squad-status header{display:grid;gap:4px}.absolute-voice-agent-squad-status header span{color:#7dd3fc;font-size:12px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-agent-squad-status header strong{font-size:20px}.absolute-voice-agent-squad-status p{color:#cbd5e1}.absolute-voice-agent-squad-status div{display:grid;gap:6px;grid-template-columns:max-content 1fr;margin:14px 0}.absolute-voice-agent-squad-status div span{color:#94a3b8}.absolute-voice-agent-squad-status ul{display:grid;gap:8px;list-style:none;margin:0;padding:0}.absolute-voice-agent-squad-status li{background:#020617;border:1px solid #1e293b;border-radius:14px;padding:10px}.absolute-voice-agent-squad-status li span{color:#94a3b8;display:block;font-size:12px}.absolute-voice-agent-squad-status li strong{display:block}.absolute-voice-agent-squad-status li em{color:#7dd3fc;font-style:normal}.absolute-voice-agent-squad-status__error{color:#fecaca;font-weight:800}`;
|