wauldo 0.7.0 → 0.7.1

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.mjs CHANGED
@@ -864,16 +864,6 @@ async function* parseSSEStream(body) {
864
864
  }
865
865
 
866
866
  // src/http_client.ts
867
- function concatUint8Arrays(arrays) {
868
- const total = arrays.reduce((n, a) => n + a.length, 0);
869
- const result = new Uint8Array(total);
870
- let offset = 0;
871
- for (const a of arrays) {
872
- result.set(a, offset);
873
- offset += a.length;
874
- }
875
- return result;
876
- }
877
867
  function validateResponse(data, typeName) {
878
868
  if (data === null || data === void 0) {
879
869
  throw new ServerError(`Invalid ${typeName}: response is null`, 0);
@@ -1008,51 +998,6 @@ var HttpClient = class {
1008
998
  );
1009
999
  return validateResponse(data, "RagUploadResponse");
1010
1000
  }
1011
- /**
1012
- * POST /v1/upload-file — Upload a file (PDF, DOCX, text, image) for RAG indexing.
1013
- *
1014
- * @param file - File content as Buffer/Uint8Array
1015
- * @param filename - The filename (determines content type detection)
1016
- * @param options - Optional title, tags, timeoutMs
1017
- * @returns Upload confirmation with quality scoring
1018
- */
1019
- async uploadFile(file, filename, options) {
1020
- const boundary = "----WauldoSDKBoundary";
1021
- const parts = [];
1022
- const enc = new TextEncoder();
1023
- parts.push(enc.encode(`--${boundary}\r
1024
- Content-Disposition: form-data; name="file"; filename="${filename}"\r
1025
- Content-Type: application/octet-stream\r
1026
- \r
1027
- `));
1028
- parts.push(file instanceof Uint8Array ? file : new Uint8Array(file));
1029
- parts.push(enc.encode("\r\n"));
1030
- if (options?.title) {
1031
- parts.push(enc.encode(`--${boundary}\r
1032
- Content-Disposition: form-data; name="title"\r
1033
- \r
1034
- ${options.title}\r
1035
- `));
1036
- }
1037
- if (options?.tags) {
1038
- parts.push(enc.encode(`--${boundary}\r
1039
- Content-Disposition: form-data; name="tags"\r
1040
- \r
1041
- ${options.tags}\r
1042
- `));
1043
- }
1044
- parts.push(enc.encode(`--${boundary}--\r
1045
- `));
1046
- const body = concatUint8Arrays(parts);
1047
- const data = await fetchWithRetry(
1048
- { ...this.retryConfig, headers: { ...this.retryConfig.headers, "Content-Type": `multipart/form-data; boundary=${boundary}` } },
1049
- "POST",
1050
- "/v1/upload-file",
1051
- body,
1052
- options?.timeoutMs
1053
- );
1054
- return validateResponse(data, "UploadFileResponse");
1055
- }
1056
1001
  /** POST /v1/query — Query RAG knowledge base */
1057
1002
  async ragQuery(query, topK = 5, options) {
1058
1003
  const body = { query, top_k: topK };
@@ -1095,83 +1040,17 @@ ${options.tags}\r
1095
1040
  const result = await this.ragQuery(question, 3);
1096
1041
  return result.answer ?? JSON.stringify(result.sources);
1097
1042
  }
1098
- // ── Orchestrator endpoints ───────────────────────────────────────────
1099
- /** POST /v1/orchestrator/execute — Route to best specialist agent */
1100
- async orchestrate(prompt) {
1101
- const data = await fetchWithRetry(
1102
- this.retryConfig,
1103
- "POST",
1104
- "/v1/orchestrator/execute",
1105
- { prompt }
1106
- );
1107
- return validateResponse(data, "OrchestratorResponse");
1108
- }
1109
- /** POST /v1/orchestrator/parallel — Run all 4 specialists in parallel */
1110
- async orchestrateParallel(prompt) {
1111
- const data = await fetchWithRetry(
1112
- this.retryConfig,
1113
- "POST",
1114
- "/v1/orchestrator/parallel",
1115
- { prompt }
1116
- );
1117
- return validateResponse(data, "OrchestratorResponse");
1118
- }
1119
- // ── Fact-Check endpoints ──────────────────────────────────────────────
1120
- /**
1121
- * POST /v1/fact-check — Verify claims against source context.
1122
- *
1123
- * @param request - Text and source context to verify
1124
- * @returns FactCheckResponse with verdict, action, and per-claim results
1125
- *
1126
- * @example
1127
- * ```typescript
1128
- * const result = await client.factCheck({
1129
- * text: 'Returns accepted within 60 days.',
1130
- * source_context: 'Our policy allows returns within 14 days.',
1131
- * mode: 'lexical',
1132
- * });
1133
- * console.log(result.verdict); // "rejected"
1134
- * ```
1135
- */
1136
- async factCheck(request) {
1137
- const data = await fetchWithRetry(
1138
- this.retryConfig,
1139
- "POST",
1140
- "/v1/fact-check",
1141
- request
1142
- );
1143
- return validateResponse(data, "FactCheckResponse");
1144
- }
1145
- /**
1146
- * POST /v1/verify — Verify citations in AI-generated text.
1147
- *
1148
- * @example
1149
- * ```ts
1150
- * const result = await client.verifyCitation({
1151
- * text: 'Rust was released in 2010 [Source: rust_book].',
1152
- * sources: [{ name: 'rust_book', content: 'Rust was first released in 2010.' }],
1153
- * });
1154
- * console.log(result.phantom_count); // 0
1155
- * ```
1156
- */
1157
- async verifyCitation(request) {
1158
- const data = await fetchWithRetry(
1159
- this.retryConfig,
1160
- "POST",
1161
- "/v1/verify",
1162
- request
1163
- );
1164
- return validateResponse(data, "VerifyCitationResponse");
1165
- }
1043
+ // ── Guard (Fact-Check) ─────────────────────────────────────────────
1166
1044
  /**
1167
1045
  * POST /v1/fact-check — Verify text claims against source context.
1168
1046
  *
1169
- * Guard is a hallucination firewall: checks whether LLM output is
1170
- * supported by source documents. Blocks wrong answers before users see them.
1047
+ * Guard is a hallucination firewall: checks whether LLM output is supported
1048
+ * by source documents. Blocks wrong answers before they reach users.
1171
1049
  *
1172
1050
  * @param text - The LLM-generated text to verify
1173
1051
  * @param sourceContext - The ground-truth source document(s)
1174
1052
  * @param mode - "lexical" (<1ms), "hybrid" (~50ms), or "semantic" (~500ms)
1053
+ * @param options - Optional per-request overrides
1175
1054
  *
1176
1055
  * @example
1177
1056
  * ```typescript
@@ -1179,53 +1058,41 @@ ${options.tags}\r
1179
1058
  * 'Returns accepted within 60 days',
1180
1059
  * 'Our return policy: 14 days.',
1181
1060
  * );
1182
- * if (guardIsBlocked(result)) {
1061
+ * if (result.action === 'block') {
1183
1062
  * console.log('Hallucination caught:', result.claims[0]?.reason);
1184
1063
  * }
1185
1064
  * ```
1186
1065
  */
1187
- async guard(text, sourceContext, mode = "lexical") {
1066
+ async guard(text, sourceContext, mode = "lexical", options) {
1188
1067
  const data = await fetchWithRetry(
1189
1068
  this.retryConfig,
1190
1069
  "POST",
1191
1070
  "/v1/fact-check",
1192
- { text, source_context: sourceContext, mode }
1071
+ { text, source_context: sourceContext, mode },
1072
+ options?.timeoutMs
1193
1073
  );
1194
1074
  return validateResponse(data, "GuardResponse");
1195
1075
  }
1196
- // ── Analytics & Insights endpoints ───────────────────────────────────
1197
- /**
1198
- * GET /v1/insights — ROI metrics for your API key
1199
- */
1200
- async getInsights() {
1201
- const data = await fetchWithRetry(
1202
- this.retryConfig,
1203
- "GET",
1204
- "/v1/insights"
1205
- );
1206
- return validateResponse(data, "InsightsResponse");
1207
- }
1208
- /**
1209
- * GET /v1/analytics — Usage analytics and cache performance
1210
- */
1211
- async getAnalytics(minutes = 60) {
1076
+ // ── Orchestrator endpoints ───────────────────────────────────────────
1077
+ /** POST /v1/orchestrator/execute — Route to best specialist agent */
1078
+ async orchestrate(prompt) {
1212
1079
  const data = await fetchWithRetry(
1213
1080
  this.retryConfig,
1214
- "GET",
1215
- `/v1/analytics?minutes=${minutes}`
1081
+ "POST",
1082
+ "/v1/orchestrator/execute",
1083
+ { prompt }
1216
1084
  );
1217
- return validateResponse(data, "AnalyticsResponse");
1085
+ return validateResponse(data, "OrchestratorResponse");
1218
1086
  }
1219
- /**
1220
- * GET /v1/analytics/traffic — Per-tenant traffic monitoring
1221
- */
1222
- async getAnalyticsTraffic() {
1087
+ /** POST /v1/orchestrator/parallel — Run all 4 specialists in parallel */
1088
+ async orchestrateParallel(prompt) {
1223
1089
  const data = await fetchWithRetry(
1224
1090
  this.retryConfig,
1225
- "GET",
1226
- "/v1/analytics/traffic"
1091
+ "POST",
1092
+ "/v1/orchestrator/parallel",
1093
+ { prompt }
1227
1094
  );
1228
- return validateResponse(data, "TrafficSummary");
1095
+ return validateResponse(data, "OrchestratorResponse");
1229
1096
  }
1230
1097
  };
1231
1098
 
@@ -1330,146 +1197,6 @@ var MockHttpClient = class {
1330
1197
  this.record("conversation", options);
1331
1198
  return new Conversation(this, options);
1332
1199
  }
1333
- async uploadFile(_file, filename, options) {
1334
- this.record("uploadFile", filename, options);
1335
- return {
1336
- document_id: "mock-doc-file-1",
1337
- chunks_count: 5,
1338
- indexed_at: (/* @__PURE__ */ new Date()).toISOString(),
1339
- content_type: "application/pdf",
1340
- trace_id: "mock-trace-1",
1341
- quality: {
1342
- score: 0.85,
1343
- label: "good",
1344
- word_count: 1200,
1345
- line_density: 8.5,
1346
- avg_line_length: 72,
1347
- paragraph_count: 15
1348
- }
1349
- };
1350
- }
1351
- async factCheck(request) {
1352
- this.record("factCheck", request);
1353
- const hasConflict = request.text !== request.source_context;
1354
- return {
1355
- verdict: hasConflict ? "rejected" : "verified",
1356
- action: hasConflict ? "block" : "allow",
1357
- hallucination_rate: hasConflict ? 1 : 0,
1358
- mode: request.mode ?? "lexical",
1359
- total_claims: 1,
1360
- supported_claims: hasConflict ? 0 : 1,
1361
- confidence: hasConflict ? 0.25 : 0.92,
1362
- claims: [{
1363
- text: request.text,
1364
- claim_type: "factual",
1365
- supported: !hasConflict,
1366
- confidence: hasConflict ? 0.25 : 0.92,
1367
- confidence_label: hasConflict ? "low" : "high",
1368
- verdict: hasConflict ? "rejected" : "verified",
1369
- action: hasConflict ? "block" : "allow",
1370
- reason: hasConflict ? "numerical_mismatch" : null,
1371
- evidence: request.source_context
1372
- }],
1373
- processing_time_ms: 1
1374
- };
1375
- }
1376
- async guard(text, sourceContext, mode = "lexical") {
1377
- this.record("guard", text, sourceContext, mode);
1378
- return {
1379
- verdict: "verified",
1380
- action: "allow",
1381
- hallucination_rate: 0,
1382
- mode,
1383
- total_claims: 1,
1384
- supported_claims: 1,
1385
- confidence: 0.95,
1386
- claims: [{
1387
- text,
1388
- claim_type: "Fact",
1389
- supported: true,
1390
- confidence: 0.95,
1391
- confidence_label: "high",
1392
- verdict: "verified",
1393
- action: "allow",
1394
- reason: null,
1395
- evidence: sourceContext
1396
- }],
1397
- processing_time_ms: 0
1398
- };
1399
- }
1400
- async verifyCitation(request) {
1401
- this.record("verifyCitation", request);
1402
- const citations = request.text.match(/\[(?:Source:\s*[^\]]+|\d+|Ref:\s*[^\]]+)\]/g) ?? [];
1403
- const sentences = request.text.split(/[.!?]+/).filter((s) => s.trim().length > 0);
1404
- const citedSentences = sentences.filter((s) => /\[(?:Source:\s*[^\]]+|\d+|Ref:\s*[^\]]+)\]/.test(s));
1405
- const ratio = sentences.length > 0 ? citedSentences.length / sentences.length : 0;
1406
- return {
1407
- citation_ratio: ratio,
1408
- has_sufficient_citations: ratio >= (request.threshold ?? 0.5),
1409
- sentence_count: sentences.length,
1410
- citation_count: citations.length,
1411
- uncited_sentences: sentences.filter((s) => !/\[(?:Source:\s*[^\]]+|\d+|Ref:\s*[^\]]+)\]/.test(s)).map((s) => s.trim()),
1412
- citations: citations.map((c) => ({
1413
- citation: c,
1414
- source_name: c.replace(/[\[\]]/g, "").replace("Source: ", ""),
1415
- is_valid: (request.sources ?? []).some((src) => c.includes(src.name))
1416
- })),
1417
- phantom_count: 0,
1418
- processing_time_ms: 1
1419
- };
1420
- }
1421
- async getInsights() {
1422
- this.record("getInsights");
1423
- return {
1424
- tig_key: "mock-tig-key",
1425
- total_requests: 1250,
1426
- intelligence_requests: 980,
1427
- fallback_requests: 270,
1428
- tokens: {
1429
- baseline_total: 5e5,
1430
- real_total: 325e3,
1431
- saved_total: 175e3,
1432
- saved_percent_avg: 35
1433
- },
1434
- cost: {
1435
- estimated_usd_saved: 12.5
1436
- }
1437
- };
1438
- }
1439
- async getAnalytics(minutes = 60) {
1440
- this.record("getAnalytics", minutes);
1441
- return {
1442
- cache: {
1443
- total_requests: 450,
1444
- cache_hit_rate: 0.42,
1445
- avg_latency_ms: 180,
1446
- p95_latency_ms: 850
1447
- },
1448
- tokens: {
1449
- total_baseline: 12e4,
1450
- total_real: 78e3,
1451
- total_saved: 42e3,
1452
- avg_savings_percent: 35
1453
- },
1454
- uptime_secs: 86400
1455
- };
1456
- }
1457
- async getAnalyticsTraffic() {
1458
- this.record("getAnalyticsTraffic");
1459
- return {
1460
- total_requests_today: 3200,
1461
- total_tokens_today: 15e5,
1462
- top_tenants: [
1463
- { tenant_id: "tenant-alpha", requests_today: 1200, tokens_used: 58e4, success_rate: 0.98, avg_latency_ms: 220 },
1464
- { tenant_id: "tenant-beta", requests_today: 850, tokens_used: 42e4, success_rate: 0.96, avg_latency_ms: 310 },
1465
- { tenant_id: "tenant-gamma", requests_today: 600, tokens_used: 28e4, success_rate: 0.99, avg_latency_ms: 150 }
1466
- ],
1467
- error_rate: 0.02,
1468
- avg_latency_ms: 240,
1469
- p95_latency_ms: 890,
1470
- uptime_secs: 86400
1471
- };
1472
- }
1473
1200
  async ragAsk(question, text, source = "document") {
1474
1201
  this.record("ragAsk", question, text, source);
1475
1202
  await this.ragUpload(text, source);
@@ -1485,6 +1212,12 @@ var MockHttpClient = class {
1485
1212
  function chatContent(response) {
1486
1213
  return response.choices[0]?.message?.content ?? "";
1487
1214
  }
1215
+ function guardIsSafe(response) {
1216
+ return response.verdict === "verified";
1217
+ }
1218
+ function guardIsBlocked(response) {
1219
+ return response.action === "block";
1220
+ }
1488
1221
  export {
1489
1222
  AgentClient,
1490
1223
  ConnectionError,
@@ -1496,5 +1229,7 @@ export {
1496
1229
  ToolNotFoundError,
1497
1230
  ValidationError,
1498
1231
  WauldoError,
1499
- chatContent
1232
+ chatContent,
1233
+ guardIsBlocked,
1234
+ guardIsSafe
1500
1235
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wauldo",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Official TypeScript SDK for Wauldo — Verified AI answers from your documents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",