@absolutejs/voice 0.0.22-beta.226 → 0.0.22-beta.228
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/README.md +24 -3
- package/dist/index.js +178 -4
- package/dist/observabilityExport.d.ts +17 -0
- package/dist/readinessProfiles.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1299,8 +1299,8 @@ app.use(
|
|
|
1299
1299
|
Built-in profiles:
|
|
1300
1300
|
|
|
1301
1301
|
- `meeting-recorder`: live latency, session health, provider fallback, routing contracts, reconnect proof, and barge-in interruption proof.
|
|
1302
|
-
- `phone-agent`: carrier readiness, phone-agent smoke proof, campaign readiness proof, handoffs, provider routing contracts, audit/trace delivery health, and delivery runtime proof.
|
|
1303
|
-
- `ops-heavy`: audit evidence, operator action history, audit/trace delivery health, delivery runtime proof, and deploy-gate support.
|
|
1302
|
+
- `phone-agent`: carrier readiness, phone-agent smoke proof, campaign readiness proof, handoffs, provider routing contracts, audit/trace delivery health, customer-owned observability export delivery history, and delivery runtime proof.
|
|
1303
|
+
- `ops-heavy`: audit evidence, operator action history, audit/trace delivery health, customer-owned observability export delivery history, delivery runtime proof, and deploy-gate support.
|
|
1304
1304
|
|
|
1305
1305
|
Phone-agent fast path:
|
|
1306
1306
|
|
|
@@ -1316,6 +1316,11 @@ app.use(
|
|
|
1316
1316
|
carriers: loadCarrierMatrixInputs,
|
|
1317
1317
|
deliveryRuntime,
|
|
1318
1318
|
explain: true,
|
|
1319
|
+
observabilityExportDeliveryHistory: {
|
|
1320
|
+
store: observabilityExportDeliveryReceipts,
|
|
1321
|
+
maxAgeMs: 60 * 60 * 1000,
|
|
1322
|
+
failOnStale: true
|
|
1323
|
+
},
|
|
1319
1324
|
phoneAgentSmokes: async () => [await runPhoneSmoke()],
|
|
1320
1325
|
providerRoutingContracts: async () => [await runProviderRoutingContract()],
|
|
1321
1326
|
traceDeliveries: runtime.traceDeliveries
|
|
@@ -1334,6 +1339,9 @@ app.use(
|
|
|
1334
1339
|
audit: runtime.audit,
|
|
1335
1340
|
auditDeliveries: runtime.auditDeliveries,
|
|
1336
1341
|
deliveryRuntime,
|
|
1342
|
+
observabilityExportDeliveryHistory: {
|
|
1343
|
+
store: observabilityExportDeliveryReceipts
|
|
1344
|
+
},
|
|
1337
1345
|
traceDeliveries: runtime.traceDeliveries
|
|
1338
1346
|
}),
|
|
1339
1347
|
gate: {
|
|
@@ -2773,6 +2781,19 @@ app.use(
|
|
|
2773
2781
|
keyPrefix: 'voice/observability-exports',
|
|
2774
2782
|
kind: 's3',
|
|
2775
2783
|
label: 'S3 customer-owned observability archive'
|
|
2784
|
+
},
|
|
2785
|
+
{
|
|
2786
|
+
kind: 'sqlite',
|
|
2787
|
+
path: '.voice-runtime/observability-exports.sqlite',
|
|
2788
|
+
tableName: 'voice_observability_exports',
|
|
2789
|
+
label: 'SQLite customer-owned observability warehouse'
|
|
2790
|
+
},
|
|
2791
|
+
{
|
|
2792
|
+
connectionString: process.env.VOICE_OBSERVABILITY_EXPORT_POSTGRES_URL,
|
|
2793
|
+
kind: 'postgres',
|
|
2794
|
+
schemaName: 'voice',
|
|
2795
|
+
tableName: 'observability_exports',
|
|
2796
|
+
label: 'Postgres customer-owned observability warehouse'
|
|
2776
2797
|
}
|
|
2777
2798
|
],
|
|
2778
2799
|
deliveryReceipts: observabilityReceipts,
|
|
@@ -2811,7 +2832,7 @@ const exportReport = await buildVoiceObservabilityExport({
|
|
|
2811
2832
|
});
|
|
2812
2833
|
```
|
|
2813
2834
|
|
|
2814
|
-
The route helper exposes JSON at `/api/voice/observability-export`, an artifact index at `/api/voice/observability-export/artifacts`, per-artifact downloads at `/api/voice/observability-export/artifacts/:artifactId`, delivery at `POST /api/voice/observability-export/deliveries`, delivery history at `GET /api/voice/observability-export/deliveries`, Markdown at `/voice/observability-export.md`, and HTML at `/voice/observability-export`. Path-backed artifacts are hashed with SHA-256 by default, include byte size and freshness metadata, and can fail the export when required evidence is missing or stale. File delivery writes `manifest.json`, `artifact-index.json`, and artifact files into a customer-owned archive directory; webhook delivery posts the manifest and artifact index to a buyer-owned collector, SIEM bridge, or warehouse endpoint; S3 delivery writes the same manifest, index, and artifact files through Bun's native S3 client. Delivery receipt stores persist run id, destinations, status, and target history so operators can prove exports have been continuously healthy. Failed trace/audit deliveries fail the export report, pending deliveries warn, and every trace/audit envelope includes the linked operations-record URL when one is configured. This is the primitive to use when customers ask how voice evidence leaves the app without going through a hosted vendor dashboard.
|
|
2835
|
+
The route helper exposes JSON at `/api/voice/observability-export`, an artifact index at `/api/voice/observability-export/artifacts`, per-artifact downloads at `/api/voice/observability-export/artifacts/:artifactId`, delivery at `POST /api/voice/observability-export/deliveries`, delivery history at `GET /api/voice/observability-export/deliveries`, Markdown at `/voice/observability-export.md`, and HTML at `/voice/observability-export`. Path-backed artifacts are hashed with SHA-256 by default, include byte size and freshness metadata, and can fail the export when required evidence is missing or stale. File delivery writes `manifest.json`, `artifact-index.json`, and artifact files into a customer-owned archive directory; webhook delivery posts the manifest and artifact index to a buyer-owned collector, SIEM bridge, or warehouse endpoint; S3 delivery writes the same manifest, index, and artifact files through Bun's native S3 client; SQLite and Postgres delivery persist the manifest, artifact index, checksum metadata, status, run id, and timestamps into buyer-owned database tables. Delivery receipt stores persist run id, destinations, status, and target history so operators can prove exports have been continuously healthy. Failed trace/audit deliveries fail the export report, pending deliveries warn, and every trace/audit envelope includes the linked operations-record URL when one is configured. This is the primitive to use when customers ask how voice evidence leaves the app without going through a hosted vendor dashboard.
|
|
2815
2836
|
|
|
2816
2837
|
Pass the same report into production readiness when export health should block deploys:
|
|
2817
2838
|
|
package/dist/index.js
CHANGED
|
@@ -22448,6 +22448,7 @@ var createVoiceOpsRecoveryRoutes = (options = {}) => {
|
|
|
22448
22448
|
|
|
22449
22449
|
// src/observabilityExport.ts
|
|
22450
22450
|
import { Elysia as Elysia39 } from "elysia";
|
|
22451
|
+
import { Database } from "bun:sqlite";
|
|
22451
22452
|
import { createHash } from "crypto";
|
|
22452
22453
|
import { mkdir as mkdir4, readFile as readFile2, stat, unlink } from "fs/promises";
|
|
22453
22454
|
import { join as join3 } from "path";
|
|
@@ -23038,6 +23039,116 @@ var writeS3Object = async (input) => {
|
|
|
23038
23039
|
type: input.contentType
|
|
23039
23040
|
});
|
|
23040
23041
|
};
|
|
23042
|
+
var quoteObservabilityIdentifier = (value) => `"${value.replace(/"/g, '""')}"`;
|
|
23043
|
+
var normalizeObservabilityIdentifier = (value) => value?.trim().replace(/[^a-zA-Z0-9_]+/g, "_").replace(/^_+|_+$/g, "") || "voice_observability_exports";
|
|
23044
|
+
var buildObservabilityExportDatabaseRecord = (input) => ({
|
|
23045
|
+
artifactCount: input.artifactIndex.summary.total,
|
|
23046
|
+
artifactIndex: input.artifactIndex,
|
|
23047
|
+
checkedAt: input.checkedAt,
|
|
23048
|
+
exportStatus: input.report.status,
|
|
23049
|
+
manifest: input.report,
|
|
23050
|
+
runId: input.runId,
|
|
23051
|
+
status: input.report.status
|
|
23052
|
+
});
|
|
23053
|
+
var deliverObservabilityExportToSQLite = async (input) => {
|
|
23054
|
+
if (!input.destination.database && !input.destination.path) {
|
|
23055
|
+
throw new Error("SQLite observability export delivery requires destination.database or destination.path.");
|
|
23056
|
+
}
|
|
23057
|
+
const database = input.destination.database ?? new Database(input.destination.path, { create: true });
|
|
23058
|
+
const table = quoteObservabilityIdentifier(normalizeObservabilityIdentifier(input.destination.tableName));
|
|
23059
|
+
const record = buildObservabilityExportDatabaseRecord(input);
|
|
23060
|
+
database.exec(`CREATE TABLE IF NOT EXISTS ${table} (
|
|
23061
|
+
run_id TEXT PRIMARY KEY,
|
|
23062
|
+
checked_at INTEGER NOT NULL,
|
|
23063
|
+
status TEXT NOT NULL,
|
|
23064
|
+
export_status TEXT NOT NULL,
|
|
23065
|
+
artifact_count INTEGER NOT NULL,
|
|
23066
|
+
manifest_json TEXT NOT NULL,
|
|
23067
|
+
artifact_index_json TEXT NOT NULL,
|
|
23068
|
+
payload_json TEXT NOT NULL
|
|
23069
|
+
)`);
|
|
23070
|
+
database.query(`INSERT INTO ${table}
|
|
23071
|
+
(run_id, checked_at, status, export_status, artifact_count, manifest_json, artifact_index_json, payload_json)
|
|
23072
|
+
VALUES ($runId, $checkedAt, $status, $exportStatus, $artifactCount, $manifest, $artifactIndex, $payload)
|
|
23073
|
+
ON CONFLICT(run_id) DO UPDATE SET
|
|
23074
|
+
checked_at = excluded.checked_at,
|
|
23075
|
+
status = excluded.status,
|
|
23076
|
+
export_status = excluded.export_status,
|
|
23077
|
+
artifact_count = excluded.artifact_count,
|
|
23078
|
+
manifest_json = excluded.manifest_json,
|
|
23079
|
+
artifact_index_json = excluded.artifact_index_json,
|
|
23080
|
+
payload_json = excluded.payload_json`).run({
|
|
23081
|
+
$artifactCount: input.artifactIndex.summary.total,
|
|
23082
|
+
$artifactIndex: input.index,
|
|
23083
|
+
$checkedAt: input.checkedAt,
|
|
23084
|
+
$exportStatus: input.report.status,
|
|
23085
|
+
$manifest: input.manifest,
|
|
23086
|
+
$payload: JSON.stringify(record),
|
|
23087
|
+
$runId: input.runId,
|
|
23088
|
+
$status: input.report.status
|
|
23089
|
+
});
|
|
23090
|
+
return input.destination.path ? `sqlite://${input.destination.path}/${table.replaceAll('"', "")}` : `sqlite://memory/${table.replaceAll('"', "")}`;
|
|
23091
|
+
};
|
|
23092
|
+
var deliverObservabilityExportToPostgres = async (input) => {
|
|
23093
|
+
const sql = input.destination.sql ?? (input.destination.connectionString ? (() => {
|
|
23094
|
+
const client = new Bun.SQL(input.destination.connectionString);
|
|
23095
|
+
return { unsafe: client.unsafe.bind(client) };
|
|
23096
|
+
})() : undefined);
|
|
23097
|
+
if (!sql) {
|
|
23098
|
+
throw new Error("Postgres observability export delivery requires destination.sql or destination.connectionString.");
|
|
23099
|
+
}
|
|
23100
|
+
const schema = normalizeObservabilityIdentifier(input.destination.schemaName ?? "public");
|
|
23101
|
+
const table = normalizeObservabilityIdentifier(input.destination.tableName);
|
|
23102
|
+
const qualifiedTable = `${quoteObservabilityIdentifier(schema)}.${quoteObservabilityIdentifier(table)}`;
|
|
23103
|
+
const record = buildObservabilityExportDatabaseRecord(input);
|
|
23104
|
+
await sql.unsafe(`CREATE SCHEMA IF NOT EXISTS ${quoteObservabilityIdentifier(schema)}`);
|
|
23105
|
+
await sql.unsafe(`CREATE TABLE IF NOT EXISTS ${qualifiedTable} (
|
|
23106
|
+
run_id TEXT PRIMARY KEY,
|
|
23107
|
+
checked_at BIGINT NOT NULL,
|
|
23108
|
+
status TEXT NOT NULL,
|
|
23109
|
+
export_status TEXT NOT NULL,
|
|
23110
|
+
artifact_count INTEGER NOT NULL,
|
|
23111
|
+
manifest_json JSONB NOT NULL,
|
|
23112
|
+
artifact_index_json JSONB NOT NULL,
|
|
23113
|
+
payload JSONB NOT NULL
|
|
23114
|
+
)`);
|
|
23115
|
+
await sql.unsafe(`INSERT INTO ${qualifiedTable}
|
|
23116
|
+
(run_id, checked_at, status, export_status, artifact_count, manifest_json, artifact_index_json, payload)
|
|
23117
|
+
VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7::jsonb, $8::jsonb)
|
|
23118
|
+
ON CONFLICT (run_id) DO UPDATE SET
|
|
23119
|
+
checked_at = EXCLUDED.checked_at,
|
|
23120
|
+
status = EXCLUDED.status,
|
|
23121
|
+
export_status = EXCLUDED.export_status,
|
|
23122
|
+
artifact_count = EXCLUDED.artifact_count,
|
|
23123
|
+
manifest_json = EXCLUDED.manifest_json,
|
|
23124
|
+
artifact_index_json = EXCLUDED.artifact_index_json,
|
|
23125
|
+
payload = EXCLUDED.payload`, [
|
|
23126
|
+
input.runId,
|
|
23127
|
+
input.checkedAt,
|
|
23128
|
+
input.report.status,
|
|
23129
|
+
input.report.status,
|
|
23130
|
+
input.artifactIndex.summary.total,
|
|
23131
|
+
input.manifest,
|
|
23132
|
+
input.index,
|
|
23133
|
+
JSON.stringify(record)
|
|
23134
|
+
]);
|
|
23135
|
+
return `postgres://${schema}/${table}`;
|
|
23136
|
+
};
|
|
23137
|
+
var observabilityExportDeliveryFailureTarget = (destination) => {
|
|
23138
|
+
if (destination.kind === "file") {
|
|
23139
|
+
return destination.directory;
|
|
23140
|
+
}
|
|
23141
|
+
if (destination.kind === "s3") {
|
|
23142
|
+
return destination.bucket ? `s3://${destination.bucket}/${normalizeExportS3KeyPrefix(destination.keyPrefix)}` : normalizeExportS3KeyPrefix(destination.keyPrefix);
|
|
23143
|
+
}
|
|
23144
|
+
if (destination.kind === "sqlite") {
|
|
23145
|
+
return destination.path ?? "sqlite://memory";
|
|
23146
|
+
}
|
|
23147
|
+
if (destination.kind === "postgres") {
|
|
23148
|
+
return destination.connectionString ?? "postgres://configured-client";
|
|
23149
|
+
}
|
|
23150
|
+
return destination.url;
|
|
23151
|
+
};
|
|
23041
23152
|
var createVoiceMemoryObservabilityExportDeliveryReceiptStore = () => {
|
|
23042
23153
|
const receipts = new Map;
|
|
23043
23154
|
return {
|
|
@@ -23437,7 +23548,7 @@ var deliverVoiceObservabilityExport = async (options) => {
|
|
|
23437
23548
|
`;
|
|
23438
23549
|
const destinations = await Promise.all(options.destinations.map(async (destination) => {
|
|
23439
23550
|
const destinationId = destination.id ?? `${destination.kind}-${destination.label ?? "export"}`;
|
|
23440
|
-
const label = destination.label ?? (destination.kind === "file" ? "File observability export" : "Webhook observability export");
|
|
23551
|
+
const label = destination.label ?? (destination.kind === "file" ? "File observability export" : destination.kind === "s3" ? "S3 observability export" : destination.kind === "sqlite" ? "SQLite observability export" : destination.kind === "postgres" ? "Postgres observability export" : "Webhook observability export");
|
|
23441
23552
|
try {
|
|
23442
23553
|
if (destination.kind === "file") {
|
|
23443
23554
|
const target = join3(destination.directory, runId);
|
|
@@ -23507,6 +23618,48 @@ var deliverVoiceObservabilityExport = async (options) => {
|
|
|
23507
23618
|
target: destination.bucket ? `s3://${destination.bucket}/${rootKey}` : rootKey
|
|
23508
23619
|
};
|
|
23509
23620
|
}
|
|
23621
|
+
if (destination.kind === "sqlite") {
|
|
23622
|
+
const target = await deliverObservabilityExportToSQLite({
|
|
23623
|
+
artifactIndex,
|
|
23624
|
+
checkedAt,
|
|
23625
|
+
destination,
|
|
23626
|
+
index,
|
|
23627
|
+
manifest,
|
|
23628
|
+
report: options.report,
|
|
23629
|
+
runId
|
|
23630
|
+
});
|
|
23631
|
+
return {
|
|
23632
|
+
artifactCount: artifactIndex.summary.total,
|
|
23633
|
+
deliveredAt: Date.now(),
|
|
23634
|
+
destinationId,
|
|
23635
|
+
destinationKind: destination.kind,
|
|
23636
|
+
label,
|
|
23637
|
+
manifestBytes: byteLength(manifest),
|
|
23638
|
+
status: "delivered",
|
|
23639
|
+
target
|
|
23640
|
+
};
|
|
23641
|
+
}
|
|
23642
|
+
if (destination.kind === "postgres") {
|
|
23643
|
+
const target = await deliverObservabilityExportToPostgres({
|
|
23644
|
+
artifactIndex,
|
|
23645
|
+
checkedAt,
|
|
23646
|
+
destination,
|
|
23647
|
+
index,
|
|
23648
|
+
manifest,
|
|
23649
|
+
report: options.report,
|
|
23650
|
+
runId
|
|
23651
|
+
});
|
|
23652
|
+
return {
|
|
23653
|
+
artifactCount: artifactIndex.summary.total,
|
|
23654
|
+
deliveredAt: Date.now(),
|
|
23655
|
+
destinationId,
|
|
23656
|
+
destinationKind: destination.kind,
|
|
23657
|
+
label,
|
|
23658
|
+
manifestBytes: byteLength(manifest),
|
|
23659
|
+
status: "delivered",
|
|
23660
|
+
target
|
|
23661
|
+
};
|
|
23662
|
+
}
|
|
23510
23663
|
const controller = new AbortController;
|
|
23511
23664
|
const timeout = setTimeout(() => controller.abort(), destination.timeoutMs ?? 1e4);
|
|
23512
23665
|
try {
|
|
@@ -23551,7 +23704,7 @@ var deliverVoiceObservabilityExport = async (options) => {
|
|
|
23551
23704
|
label,
|
|
23552
23705
|
manifestBytes: byteLength(manifest),
|
|
23553
23706
|
status: "failed",
|
|
23554
|
-
target:
|
|
23707
|
+
target: observabilityExportDeliveryFailureTarget(destination)
|
|
23555
23708
|
};
|
|
23556
23709
|
}
|
|
23557
23710
|
}));
|
|
@@ -24908,6 +25061,7 @@ var profileSurfaceLabels = {
|
|
|
24908
25061
|
audit: "audit evidence configured",
|
|
24909
25062
|
auditDeliveries: "audit delivery queue configured",
|
|
24910
25063
|
deliveryRuntime: "delivery runtime configured",
|
|
25064
|
+
observabilityExportDeliveryHistory: "observability export delivery history configured",
|
|
24911
25065
|
opsActionHistory: "operator action history configured",
|
|
24912
25066
|
traceDeliveries: "trace delivery queue configured"
|
|
24913
25067
|
},
|
|
@@ -24916,6 +25070,7 @@ var profileSurfaceLabels = {
|
|
|
24916
25070
|
campaignReadiness: "campaign readiness proof configured",
|
|
24917
25071
|
carriers: "carrier readiness configured",
|
|
24918
25072
|
deliveryRuntime: "delivery runtime configured",
|
|
25073
|
+
observabilityExportDeliveryHistory: "observability export delivery history configured",
|
|
24919
25074
|
phoneAgentSmokes: "phone-agent smoke proof configured",
|
|
24920
25075
|
providerRoutingContracts: "provider routing contracts configured",
|
|
24921
25076
|
traceDeliveries: "trace delivery queue configured"
|
|
@@ -24932,6 +25087,7 @@ var profileRequiredKeys = {
|
|
|
24932
25087
|
"opsActionHistory",
|
|
24933
25088
|
"auditDeliveries",
|
|
24934
25089
|
"traceDeliveries",
|
|
25090
|
+
"observabilityExportDeliveryHistory",
|
|
24935
25091
|
"deliveryRuntime"
|
|
24936
25092
|
],
|
|
24937
25093
|
"phone-agent": [
|
|
@@ -24941,6 +25097,7 @@ var profileRequiredKeys = {
|
|
|
24941
25097
|
"providerRoutingContracts",
|
|
24942
25098
|
"auditDeliveries",
|
|
24943
25099
|
"traceDeliveries",
|
|
25100
|
+
"observabilityExportDeliveryHistory",
|
|
24944
25101
|
"deliveryRuntime"
|
|
24945
25102
|
]
|
|
24946
25103
|
};
|
|
@@ -24953,6 +25110,7 @@ var configuredProfileKeys = (options) => {
|
|
|
24953
25110
|
"campaignReadiness",
|
|
24954
25111
|
"carriers",
|
|
24955
25112
|
"deliveryRuntime",
|
|
25113
|
+
"observabilityExportDeliveryHistory",
|
|
24956
25114
|
"opsActionHistory",
|
|
24957
25115
|
"phoneAgentSmokes",
|
|
24958
25116
|
"providerRoutingContracts",
|
|
@@ -25071,6 +25229,12 @@ var profileExplanation = (profile, options, links) => {
|
|
|
25071
25229
|
key: "deliveryRuntime",
|
|
25072
25230
|
label: "Delivery runtime"
|
|
25073
25231
|
},
|
|
25232
|
+
{
|
|
25233
|
+
configured: isConfigured(options.observabilityExportDeliveryHistory),
|
|
25234
|
+
href: links.observabilityExportDeliveries,
|
|
25235
|
+
key: "observabilityExportDeliveryHistory",
|
|
25236
|
+
label: "Observability export delivery"
|
|
25237
|
+
},
|
|
25074
25238
|
{
|
|
25075
25239
|
configured: isConfigured(options.auditDeliveries),
|
|
25076
25240
|
href: links.auditDeliveries,
|
|
@@ -25109,6 +25273,12 @@ var profileExplanation = (profile, options, links) => {
|
|
|
25109
25273
|
key: "deliveryRuntime",
|
|
25110
25274
|
label: "Delivery runtime"
|
|
25111
25275
|
},
|
|
25276
|
+
{
|
|
25277
|
+
configured: isConfigured(options.observabilityExportDeliveryHistory),
|
|
25278
|
+
href: links.observabilityExportDeliveries,
|
|
25279
|
+
key: "observabilityExportDeliveryHistory",
|
|
25280
|
+
label: "Observability export delivery"
|
|
25281
|
+
},
|
|
25112
25282
|
{
|
|
25113
25283
|
configured: isConfigured(options.auditDeliveries),
|
|
25114
25284
|
href: links.auditDeliveries,
|
|
@@ -25152,6 +25322,7 @@ var createVoiceReadinessProfile = (profile, options = {}) => {
|
|
|
25152
25322
|
carriers: "/carriers",
|
|
25153
25323
|
deliveryRuntime: "/delivery-runtime",
|
|
25154
25324
|
handoffs: "/handoffs",
|
|
25325
|
+
observabilityExportDeliveries: "/api/voice/observability-export/deliveries",
|
|
25155
25326
|
phoneAgentSmoke: "/sessions",
|
|
25156
25327
|
providerRoutingContracts: "/resilience",
|
|
25157
25328
|
resilience: "/resilience",
|
|
@@ -25165,6 +25336,7 @@ var createVoiceReadinessProfile = (profile, options = {}) => {
|
|
|
25165
25336
|
deliveryRuntime: options.deliveryRuntime,
|
|
25166
25337
|
gate: options.gate,
|
|
25167
25338
|
links: links2,
|
|
25339
|
+
observabilityExportDeliveryHistory: options.observabilityExportDeliveryHistory,
|
|
25168
25340
|
phoneAgentSmokes: options.phoneAgentSmokes,
|
|
25169
25341
|
profile: profileExplanation(profile, options, links2),
|
|
25170
25342
|
proofSources: options.proofSources,
|
|
@@ -25177,6 +25349,7 @@ var createVoiceReadinessProfile = (profile, options = {}) => {
|
|
|
25177
25349
|
audit: "/audit",
|
|
25178
25350
|
auditDeliveries: "/audit/deliveries",
|
|
25179
25351
|
deliveryRuntime: "/delivery-runtime",
|
|
25352
|
+
observabilityExportDeliveries: "/api/voice/observability-export/deliveries",
|
|
25180
25353
|
opsActions: "/voice/ops-actions",
|
|
25181
25354
|
traceDeliveries: "/traces/deliveries"
|
|
25182
25355
|
}, options.links);
|
|
@@ -25186,6 +25359,7 @@ var createVoiceReadinessProfile = (profile, options = {}) => {
|
|
|
25186
25359
|
deliveryRuntime: options.deliveryRuntime,
|
|
25187
25360
|
gate: options.gate,
|
|
25188
25361
|
links,
|
|
25362
|
+
observabilityExportDeliveryHistory: options.observabilityExportDeliveryHistory,
|
|
25189
25363
|
opsActionHistory,
|
|
25190
25364
|
profile: profileExplanation(profile, options, links),
|
|
25191
25365
|
proofSources: options.proofSources,
|
|
@@ -26680,7 +26854,7 @@ var createVoiceTraceDeliveryRoutes = (options) => {
|
|
|
26680
26854
|
return routes;
|
|
26681
26855
|
};
|
|
26682
26856
|
// src/sqliteStore.ts
|
|
26683
|
-
import { Database } from "bun:sqlite";
|
|
26857
|
+
import { Database as Database2 } from "bun:sqlite";
|
|
26684
26858
|
var normalizeTableNameSegment = (value) => value.trim().replace(/[^a-zA-Z0-9_]+/g, "_").replace(/^_+|_+$/g, "") || "voice";
|
|
26685
26859
|
var resolveTableName = (input) => {
|
|
26686
26860
|
if (input.options.tableName) {
|
|
@@ -26691,7 +26865,7 @@ var resolveTableName = (input) => {
|
|
|
26691
26865
|
return `${prefix}_${fallback}`;
|
|
26692
26866
|
};
|
|
26693
26867
|
var openVoiceSQLiteDatabase = (path) => {
|
|
26694
|
-
const database = new
|
|
26868
|
+
const database = new Database2(path, {
|
|
26695
26869
|
create: true
|
|
26696
26870
|
});
|
|
26697
26871
|
database.exec("PRAGMA journal_mode = WAL;");
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
2
|
import type { S3Client, S3Options } from 'bun';
|
|
3
|
+
import { Database } from 'bun:sqlite';
|
|
3
4
|
import { type VoiceAuditSinkDeliveryQueueSummary, type VoiceAuditSinkDeliveryRecord, type VoiceAuditSinkDeliveryStore } from './auditSinks';
|
|
4
5
|
import type { VoiceAuditEventStore, VoiceAuditEventType } from './audit';
|
|
5
6
|
import { type VoiceOperationsRecord } from './operationsRecord';
|
|
6
7
|
import { type VoiceTraceSinkDeliveryQueueSummary } from './queue';
|
|
7
8
|
import { type StoredVoiceTraceEvent, type VoiceTraceEventStore, type VoiceTraceEventType, type VoiceTraceRedactionConfig, type VoiceTraceSinkDeliveryRecord, type VoiceTraceSinkDeliveryStore, type VoiceTraceSummary } from './trace';
|
|
9
|
+
import type { VoicePostgresClient } from './postgresStore';
|
|
8
10
|
export type VoiceObservabilityExportStatus = 'fail' | 'pass' | 'warn';
|
|
9
11
|
export type VoiceObservabilityExportArtifactKind = 'incident' | 'markdown' | 'operations-record' | 'proof-pack' | 'readiness' | 'screenshot' | 'slo' | 'trace' | 'audit' | 'custom';
|
|
10
12
|
export type VoiceObservabilityExportArtifactChecksum = {
|
|
@@ -123,6 +125,21 @@ export type VoiceObservabilityExportDeliveryDestination = {
|
|
|
123
125
|
kind: 's3';
|
|
124
126
|
label?: string;
|
|
125
127
|
}) | {
|
|
128
|
+
database?: Database;
|
|
129
|
+
id?: string;
|
|
130
|
+
kind: 'sqlite';
|
|
131
|
+
label?: string;
|
|
132
|
+
path?: string;
|
|
133
|
+
tableName?: string;
|
|
134
|
+
} | {
|
|
135
|
+
connectionString?: string;
|
|
136
|
+
id?: string;
|
|
137
|
+
kind: 'postgres';
|
|
138
|
+
label?: string;
|
|
139
|
+
schemaName?: string;
|
|
140
|
+
sql?: VoicePostgresClient;
|
|
141
|
+
tableName?: string;
|
|
142
|
+
} | {
|
|
126
143
|
fetch?: typeof fetch;
|
|
127
144
|
headers?: Record<string, string>;
|
|
128
145
|
id?: string;
|
|
@@ -10,6 +10,7 @@ export type VoiceReadinessProfileOptions = {
|
|
|
10
10
|
explain?: boolean;
|
|
11
11
|
gate?: VoiceProductionReadinessRoutesOptions['gate'];
|
|
12
12
|
links?: VoiceProductionReadinessRoutesOptions['links'];
|
|
13
|
+
observabilityExportDeliveryHistory?: VoiceProductionReadinessRoutesOptions['observabilityExportDeliveryHistory'];
|
|
13
14
|
opsActionHistory?: VoiceProductionReadinessOpsActionHistoryOptions;
|
|
14
15
|
phoneAgentSmokes?: VoiceProductionReadinessRoutesOptions['phoneAgentSmokes'];
|
|
15
16
|
proofSources?: VoiceProductionReadinessRoutesOptions['proofSources'];
|