@absolutejs/voice 0.0.22-beta.106 → 0.0.22-beta.107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -11132,6 +11132,71 @@ var summarizeSection = (report) => ({
11132
11132
  total: report.total
11133
11133
  });
11134
11134
  var hasWork = (options) => Boolean(options.store || options.scenarios?.length || options.fixtures?.length || options.fixtureStore || options.tools?.length || options.outcomes?.contracts.length);
11135
+ var collectSimulationActions = (input) => {
11136
+ const actions = [];
11137
+ if (input.sessions?.failed) {
11138
+ const firstFailed = input.sessions.sessions.find((session) => session.status === "fail");
11139
+ actions.push({
11140
+ description: firstFailed ? `Inspect session ${firstFailed.sessionId}; at least one quality metric is outside threshold.` : "Inspect failing session quality reports.",
11141
+ href: input.links?.sessions,
11142
+ label: "Review failing session quality",
11143
+ section: "sessions",
11144
+ severity: "error"
11145
+ });
11146
+ }
11147
+ for (const scenario of input.scenarios?.scenarios ?? []) {
11148
+ if (scenario.status !== "fail") {
11149
+ continue;
11150
+ }
11151
+ const issue = scenario.issues[0] ?? scenario.sessions.find((session) => session.issues.length > 0)?.issues[0] ?? "Scenario did not meet its expected trace conditions.";
11152
+ actions.push({
11153
+ description: `${scenario.label}: ${issue}`,
11154
+ href: input.links?.scenarios,
11155
+ label: `Fix scenario ${scenario.label}`,
11156
+ section: "scenarios",
11157
+ severity: "error"
11158
+ });
11159
+ }
11160
+ for (const fixture of input.fixtures?.fixtures ?? []) {
11161
+ if (fixture.status !== "fail") {
11162
+ continue;
11163
+ }
11164
+ const failedScenario = fixture.report.scenarios.find((scenario) => scenario.status === "fail");
11165
+ actions.push({
11166
+ description: failedScenario ? `${fixture.label}: ${failedScenario.label} failed.` : `${fixture.label}: fixture simulation failed.`,
11167
+ href: input.links?.fixtures,
11168
+ label: `Update fixture ${fixture.label}`,
11169
+ section: "fixtures",
11170
+ severity: "error"
11171
+ });
11172
+ }
11173
+ for (const tool of input.tools?.contracts ?? []) {
11174
+ if (tool.pass) {
11175
+ continue;
11176
+ }
11177
+ const issue = tool.issues[0] ?? tool.cases.find((testCase) => !testCase.pass)?.issues[0];
11178
+ actions.push({
11179
+ description: issue?.message ?? `${tool.toolName} contract failed.`,
11180
+ href: input.links?.tools,
11181
+ label: `Fix tool contract ${tool.label ?? tool.contractId}`,
11182
+ section: "tools",
11183
+ severity: "error"
11184
+ });
11185
+ }
11186
+ for (const outcome of input.outcomes?.contracts ?? []) {
11187
+ if (outcome.pass) {
11188
+ continue;
11189
+ }
11190
+ actions.push({
11191
+ description: outcome.issues[0]?.message ?? `${outcome.label ?? outcome.contractId} is missing required outcome evidence.`,
11192
+ href: input.links?.outcomes,
11193
+ label: `Fix outcome ${outcome.label ?? outcome.contractId}`,
11194
+ section: "outcomes",
11195
+ severity: "error"
11196
+ });
11197
+ }
11198
+ return actions;
11199
+ };
11135
11200
  var runVoiceSimulationSuite = async (options) => {
11136
11201
  const include = options.include ?? {};
11137
11202
  const shouldRunSessions = include.sessions ?? Boolean(options.store || !hasWork(options));
@@ -11162,7 +11227,16 @@ var runVoiceSimulationSuite = async (options) => {
11162
11227
  const sections = [sessions, scenarios, fixtures, tools, outcomes].filter((report) => Boolean(report));
11163
11228
  const failed = sections.filter((section) => section.status === "fail").length;
11164
11229
  const passed = sections.length - failed;
11230
+ const actions = collectSimulationActions({
11231
+ fixtures,
11232
+ links: options.actionLinks,
11233
+ outcomes,
11234
+ scenarios,
11235
+ sessions,
11236
+ tools
11237
+ });
11165
11238
  return {
11239
+ actions,
11166
11240
  checkedAt: Date.now(),
11167
11241
  failed,
11168
11242
  fixtures,
@@ -11188,9 +11262,13 @@ var renderSection = (label, summary) => {
11188
11262
  }
11189
11263
  return `<article class="${escapeHtml20(summary.status)}"><span>${escapeHtml20(label)}</span><strong>${escapeHtml20(summary.status)}</strong><p>${summary.passed}/${summary.total} passed, ${summary.failed} failed.</p></article>`;
11190
11264
  };
11265
+ var renderAction = (action) => {
11266
+ const content = `<strong>${escapeHtml20(action.label)}</strong><p>${escapeHtml20(action.description)}</p><span>${escapeHtml20(action.section)} / ${escapeHtml20(action.severity)}</span>`;
11267
+ return action.href ? `<a class="action" href="${escapeHtml20(action.href)}">${content}</a>` : `<article class="action">${content}</article>`;
11268
+ };
11191
11269
  var renderVoiceSimulationSuiteHTML = (report, options = {}) => {
11192
11270
  const title = options.title ?? "Voice Simulation Suite";
11193
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml20(title)}</title><style>body{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1080px;padding:32px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.18),rgba(59,130,246,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#93c5fd;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.badge{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin:18px 0}.grid article{background:#151d27;border:1px solid #283544;border-radius:18px;padding:16px}.grid span{color:#aab5c0}.grid strong{display:block;font-size:2rem;margin:.25rem 0;text-transform:uppercase}pre{background:#151d27;border:1px solid #283544;border-radius:18px;overflow:auto;padding:16px}</style></head><body><main><section class="hero"><p class="eyebrow">Pre-production proof</p><h1>${escapeHtml20(title)}</h1><p>One report for session quality, scenario evals, fixture simulations, tool contracts, and outcome contracts.</p><p class="badge ${escapeHtml20(report.status)}">Status: ${escapeHtml20(report.status)}</p><section class="grid">${renderSection("Sessions", report.summary.sessions)}${renderSection("Scenarios", report.summary.scenarios)}${renderSection("Fixtures", report.summary.fixtures)}${renderSection("Tools", report.summary.tools)}${renderSection("Outcomes", report.summary.outcomes)}</section></section><pre>${escapeHtml20(JSON.stringify(report.summary, null, 2))}</pre></main></body></html>`;
11271
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml20(title)}</title><style>body{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1080px;padding:32px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.18),rgba(59,130,246,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#93c5fd;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.badge{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.grid,.actions{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin:18px 0}.grid article,.action{background:#151d27;border:1px solid #283544;border-radius:18px;color:inherit;padding:16px;text-decoration:none}.grid span,.action span{color:#aab5c0}.grid strong{display:block;font-size:2rem;margin:.25rem 0;text-transform:uppercase}.action strong{display:block;color:#f8f3e7;margin-bottom:.35rem}.action p{color:#d8dee6;margin:.3rem 0 .6rem}pre{background:#151d27;border:1px solid #283544;border-radius:18px;overflow:auto;padding:16px}</style></head><body><main><section class="hero"><p class="eyebrow">Pre-production proof</p><h1>${escapeHtml20(title)}</h1><p>One report for session quality, scenario evals, fixture simulations, tool contracts, and outcome contracts.</p><p class="badge ${escapeHtml20(report.status)}">Status: ${escapeHtml20(report.status)}</p><section class="grid">${renderSection("Sessions", report.summary.sessions)}${renderSection("Scenarios", report.summary.scenarios)}${renderSection("Fixtures", report.summary.fixtures)}${renderSection("Tools", report.summary.tools)}${renderSection("Outcomes", report.summary.outcomes)}</section></section><h2>Actions</h2><section class="actions">${report.actions.length > 0 ? report.actions.map(renderAction).join("") : '<article class="action"><strong>No action required</strong><p>All enabled simulation sections are passing.</p></article>'}</section><pre>${escapeHtml20(JSON.stringify({ summary: report.summary, actions: report.actions }, null, 2))}</pre></main></body></html>`;
11194
11272
  };
11195
11273
  var createVoiceSimulationSuiteRoutes = (options) => {
11196
11274
  const path = options.path ?? "/api/voice/simulations";
@@ -7,6 +7,7 @@ import type { VoiceTraceEventStore } from './trace';
7
7
  import type { VoiceSessionRecord } from './types';
8
8
  export type VoiceSimulationSuiteStatus = 'pass' | 'fail';
9
9
  export type VoiceSimulationSuiteReport = {
10
+ actions: VoiceSimulationSuiteAction[];
10
11
  checkedAt: number;
11
12
  failed: number;
12
13
  fixtures?: VoiceScenarioFixtureEvalReport;
@@ -25,6 +26,13 @@ export type VoiceSimulationSuiteReport = {
25
26
  tools?: VoiceToolContractSuiteReport;
26
27
  total: number;
27
28
  };
29
+ export type VoiceSimulationSuiteAction = {
30
+ description: string;
31
+ href?: string;
32
+ label: string;
33
+ section: 'fixtures' | 'outcomes' | 'scenarios' | 'sessions' | 'tools';
34
+ severity: 'error' | 'warning';
35
+ };
28
36
  export type VoiceSimulationSuiteSectionSummary = {
29
37
  failed: number;
30
38
  passed: number;
@@ -32,6 +40,13 @@ export type VoiceSimulationSuiteSectionSummary = {
32
40
  total: number;
33
41
  };
34
42
  export type VoiceSimulationSuiteOptions<TSession extends VoiceSessionRecord = VoiceSessionRecord> = {
43
+ actionLinks?: {
44
+ fixtures?: string;
45
+ outcomes?: string;
46
+ scenarios?: string;
47
+ sessions?: string;
48
+ tools?: string;
49
+ };
35
50
  fixtures?: VoiceScenarioFixture[];
36
51
  fixtureStore?: VoiceScenarioFixtureStore;
37
52
  include?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.106",
3
+ "version": "0.0.22-beta.107",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",