ai-output-assert 0.3.0

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.
Files changed (142) hide show
  1. package/README.md +183 -0
  2. package/dist/__tests__/matchers/content.test.d.ts +2 -0
  3. package/dist/__tests__/matchers/content.test.d.ts.map +1 -0
  4. package/dist/__tests__/matchers/content.test.js +66 -0
  5. package/dist/__tests__/matchers/content.test.js.map +1 -0
  6. package/dist/__tests__/matchers/format.test.d.ts +2 -0
  7. package/dist/__tests__/matchers/format.test.d.ts.map +1 -0
  8. package/dist/__tests__/matchers/format.test.js +100 -0
  9. package/dist/__tests__/matchers/format.test.js.map +1 -0
  10. package/dist/__tests__/matchers/quality.test.d.ts +2 -0
  11. package/dist/__tests__/matchers/quality.test.d.ts.map +1 -0
  12. package/dist/__tests__/matchers/quality.test.js +98 -0
  13. package/dist/__tests__/matchers/quality.test.js.map +1 -0
  14. package/dist/__tests__/matchers/safety.test.d.ts +2 -0
  15. package/dist/__tests__/matchers/safety.test.d.ts.map +1 -0
  16. package/dist/__tests__/matchers/safety.test.js +120 -0
  17. package/dist/__tests__/matchers/safety.test.js.map +1 -0
  18. package/dist/__tests__/setup.test.d.ts +2 -0
  19. package/dist/__tests__/setup.test.d.ts.map +1 -0
  20. package/dist/__tests__/setup.test.js +49 -0
  21. package/dist/__tests__/setup.test.js.map +1 -0
  22. package/dist/__tests__/types.test.d.ts +2 -0
  23. package/dist/__tests__/types.test.d.ts.map +1 -0
  24. package/dist/__tests__/types.test.js +50 -0
  25. package/dist/__tests__/types.test.js.map +1 -0
  26. package/dist/__tests__/utils/cosine-similarity.test.d.ts +2 -0
  27. package/dist/__tests__/utils/cosine-similarity.test.d.ts.map +1 -0
  28. package/dist/__tests__/utils/cosine-similarity.test.js +30 -0
  29. package/dist/__tests__/utils/cosine-similarity.test.js.map +1 -0
  30. package/dist/__tests__/utils/embedding-cache.test.d.ts +2 -0
  31. package/dist/__tests__/utils/embedding-cache.test.d.ts.map +1 -0
  32. package/dist/__tests__/utils/embedding-cache.test.js +41 -0
  33. package/dist/__tests__/utils/embedding-cache.test.js.map +1 -0
  34. package/dist/__tests__/utils/json-extract.test.d.ts +2 -0
  35. package/dist/__tests__/utils/json-extract.test.d.ts.map +1 -0
  36. package/dist/__tests__/utils/json-extract.test.js +32 -0
  37. package/dist/__tests__/utils/json-extract.test.js.map +1 -0
  38. package/dist/__tests__/utils/luhn.test.d.ts +2 -0
  39. package/dist/__tests__/utils/luhn.test.d.ts.map +1 -0
  40. package/dist/__tests__/utils/luhn.test.js +25 -0
  41. package/dist/__tests__/utils/luhn.test.js.map +1 -0
  42. package/dist/__tests__/utils/ngrams.test.d.ts +2 -0
  43. package/dist/__tests__/utils/ngrams.test.d.ts.map +1 -0
  44. package/dist/__tests__/utils/ngrams.test.js +28 -0
  45. package/dist/__tests__/utils/ngrams.test.js.map +1 -0
  46. package/dist/__tests__/utils/regex-escape.test.d.ts +2 -0
  47. package/dist/__tests__/utils/regex-escape.test.d.ts.map +1 -0
  48. package/dist/__tests__/utils/regex-escape.test.js +48 -0
  49. package/dist/__tests__/utils/regex-escape.test.js.map +1 -0
  50. package/dist/__tests__/utils/sentences.test.d.ts +2 -0
  51. package/dist/__tests__/utils/sentences.test.d.ts.map +1 -0
  52. package/dist/__tests__/utils/sentences.test.js +39 -0
  53. package/dist/__tests__/utils/sentences.test.js.map +1 -0
  54. package/dist/__tests__/utils/tokenizer.test.d.ts +2 -0
  55. package/dist/__tests__/utils/tokenizer.test.d.ts.map +1 -0
  56. package/dist/__tests__/utils/tokenizer.test.js +25 -0
  57. package/dist/__tests__/utils/tokenizer.test.js.map +1 -0
  58. package/dist/catalogs/hedging-phrases.d.ts +4 -0
  59. package/dist/catalogs/hedging-phrases.d.ts.map +1 -0
  60. package/dist/catalogs/hedging-phrases.js +49 -0
  61. package/dist/catalogs/hedging-phrases.js.map +1 -0
  62. package/dist/catalogs/pii-patterns.d.ts +3 -0
  63. package/dist/catalogs/pii-patterns.d.ts.map +1 -0
  64. package/dist/catalogs/pii-patterns.js +35 -0
  65. package/dist/catalogs/pii-patterns.js.map +1 -0
  66. package/dist/catalogs/toxic-words.d.ts +3 -0
  67. package/dist/catalogs/toxic-words.d.ts.map +1 -0
  68. package/dist/catalogs/toxic-words.js +32 -0
  69. package/dist/catalogs/toxic-words.js.map +1 -0
  70. package/dist/index.d.ts +21 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +76 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/matchers/content.d.ts +6 -0
  75. package/dist/matchers/content.d.ts.map +1 -0
  76. package/dist/matchers/content.js +54 -0
  77. package/dist/matchers/content.js.map +1 -0
  78. package/dist/matchers/format.d.ts +6 -0
  79. package/dist/matchers/format.d.ts.map +1 -0
  80. package/dist/matchers/format.js +121 -0
  81. package/dist/matchers/format.js.map +1 -0
  82. package/dist/matchers/quality.d.ts +9 -0
  83. package/dist/matchers/quality.d.ts.map +1 -0
  84. package/dist/matchers/quality.js +107 -0
  85. package/dist/matchers/quality.js.map +1 -0
  86. package/dist/matchers/safety.d.ts +6 -0
  87. package/dist/matchers/safety.d.ts.map +1 -0
  88. package/dist/matchers/safety.js +87 -0
  89. package/dist/matchers/safety.js.map +1 -0
  90. package/dist/matchers/semantic.d.ts +12 -0
  91. package/dist/matchers/semantic.d.ts.map +1 -0
  92. package/dist/matchers/semantic.js +79 -0
  93. package/dist/matchers/semantic.js.map +1 -0
  94. package/dist/matchers/structural.d.ts +7 -0
  95. package/dist/matchers/structural.d.ts.map +1 -0
  96. package/dist/matchers/structural.js +154 -0
  97. package/dist/matchers/structural.js.map +1 -0
  98. package/dist/matchers/tone.d.ts +9 -0
  99. package/dist/matchers/tone.d.ts.map +1 -0
  100. package/dist/matchers/tone.js +138 -0
  101. package/dist/matchers/tone.js.map +1 -0
  102. package/dist/setup.d.ts +4 -0
  103. package/dist/setup.d.ts.map +1 -0
  104. package/dist/setup.js +92 -0
  105. package/dist/setup.js.map +1 -0
  106. package/dist/types.d.ts +43 -0
  107. package/dist/types.d.ts.map +1 -0
  108. package/dist/types.js +3 -0
  109. package/dist/types.js.map +1 -0
  110. package/dist/utils/cosine-similarity.d.ts +2 -0
  111. package/dist/utils/cosine-similarity.d.ts.map +1 -0
  112. package/dist/utils/cosine-similarity.js +18 -0
  113. package/dist/utils/cosine-similarity.js.map +1 -0
  114. package/dist/utils/embedding-cache.d.ts +3 -0
  115. package/dist/utils/embedding-cache.d.ts.map +1 -0
  116. package/dist/utils/embedding-cache.js +14 -0
  117. package/dist/utils/embedding-cache.js.map +1 -0
  118. package/dist/utils/json-extract.d.ts +2 -0
  119. package/dist/utils/json-extract.d.ts.map +1 -0
  120. package/dist/utils/json-extract.js +8 -0
  121. package/dist/utils/json-extract.js.map +1 -0
  122. package/dist/utils/luhn.d.ts +2 -0
  123. package/dist/utils/luhn.d.ts.map +1 -0
  124. package/dist/utils/luhn.js +22 -0
  125. package/dist/utils/luhn.js.map +1 -0
  126. package/dist/utils/ngrams.d.ts +2 -0
  127. package/dist/utils/ngrams.d.ts.map +1 -0
  128. package/dist/utils/ngrams.js +13 -0
  129. package/dist/utils/ngrams.js.map +1 -0
  130. package/dist/utils/regex-escape.d.ts +2 -0
  131. package/dist/utils/regex-escape.d.ts.map +1 -0
  132. package/dist/utils/regex-escape.js +7 -0
  133. package/dist/utils/regex-escape.js.map +1 -0
  134. package/dist/utils/sentences.d.ts +2 -0
  135. package/dist/utils/sentences.d.ts.map +1 -0
  136. package/dist/utils/sentences.js +36 -0
  137. package/dist/utils/sentences.js.map +1 -0
  138. package/dist/utils/tokenizer.d.ts +2 -0
  139. package/dist/utils/tokenizer.d.ts.map +1 -0
  140. package/dist/utils/tokenizer.js +7 -0
  141. package/dist/utils/tokenizer.js.map +1 -0
  142. package/package.json +36 -0
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_PII_PATTERNS = void 0;
4
+ const luhn_1 = require("../utils/luhn");
5
+ exports.DEFAULT_PII_PATTERNS = [
6
+ {
7
+ type: 'email',
8
+ pattern: /[\w.+-]+@[\w-]+\.[\w.]+/,
9
+ label: 'Email Address',
10
+ },
11
+ {
12
+ type: 'ssn',
13
+ pattern: /\b\d{3}-\d{2}-\d{4}\b/,
14
+ label: 'SSN',
15
+ validate: (v) => v.replace(/-/g, '').length === 9,
16
+ },
17
+ {
18
+ type: 'credit-card',
19
+ pattern: /\b(?:\d{4}[\s-]?){3}\d{4}\b/,
20
+ label: 'Credit Card',
21
+ validate: (v) => (0, luhn_1.luhnCheck)(v.replace(/[\s-]/g, '')),
22
+ },
23
+ {
24
+ type: 'phone',
25
+ pattern: /\b(?:\+1[\s-]?)?\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}\b/,
26
+ label: 'Phone Number',
27
+ },
28
+ {
29
+ type: 'ip-address',
30
+ pattern: /\b(?:\d{1,3}\.){3}\d{1,3}\b/,
31
+ label: 'IP Address',
32
+ validate: (v) => v.split('.').every((n) => parseInt(n, 10) <= 255),
33
+ },
34
+ ];
35
+ //# sourceMappingURL=pii-patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pii-patterns.js","sourceRoot":"","sources":["../../src/catalogs/pii-patterns.ts"],"names":[],"mappings":";;;AAAA,wCAA0C;AAG7B,QAAA,oBAAoB,GAAiB;IAChD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,yBAAyB;QAClC,KAAK,EAAE,eAAe;KACvB;IACD;QACE,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,uBAAuB;QAChC,KAAK,EAAE,KAAK;QACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC;KAClD;IACD;QACE,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,6BAA6B;QACtC,KAAK,EAAE,aAAa;QACpB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,gBAAS,EAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;KACpD;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,qDAAqD;QAC9D,KAAK,EAAE,cAAc;KACtB;IACD;QACE,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,6BAA6B;QACtC,KAAK,EAAE,YAAY;QACnB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;KACnE;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ToxicWord } from '../types';
2
+ export declare const DEFAULT_TOXIC_WORDS: ToxicWord[];
3
+ //# sourceMappingURL=toxic-words.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toxic-words.d.ts","sourceRoot":"","sources":["../../src/catalogs/toxic-words.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,eAAO,MAAM,mBAAmB,EAAE,SAAS,EA2B1C,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_TOXIC_WORDS = void 0;
4
+ exports.DEFAULT_TOXIC_WORDS = [
5
+ // critical — slurs
6
+ { word: 'nigger', severity: 'critical' },
7
+ { word: 'nigga', severity: 'critical' },
8
+ { word: 'faggot', severity: 'critical' },
9
+ { word: 'kike', severity: 'critical' },
10
+ { word: 'spic', severity: 'critical' },
11
+ { word: 'chink', severity: 'critical' },
12
+ { word: 'wetback', severity: 'critical' },
13
+ { word: 'cunt', severity: 'critical' },
14
+ // warning — profanity
15
+ { word: 'fuck', severity: 'warning' },
16
+ { word: 'shit', severity: 'warning' },
17
+ { word: 'asshole', severity: 'warning' },
18
+ { word: 'bitch', severity: 'warning' },
19
+ { word: 'bastard', severity: 'warning' },
20
+ { word: 'damn', severity: 'warning' },
21
+ { word: 'hell', severity: 'warning' },
22
+ { word: 'piss', severity: 'warning' },
23
+ // info — mild
24
+ { word: 'crap', severity: 'info' },
25
+ { word: 'sucks', severity: 'info' },
26
+ { word: 'idiot', severity: 'info' },
27
+ { word: 'stupid', severity: 'info' },
28
+ { word: 'moron', severity: 'info' },
29
+ { word: 'dumb', severity: 'info' },
30
+ { word: 'loser', severity: 'info' },
31
+ ];
32
+ //# sourceMappingURL=toxic-words.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toxic-words.js","sourceRoot":"","sources":["../../src/catalogs/toxic-words.ts"],"names":[],"mappings":";;;AAEa,QAAA,mBAAmB,GAAgB;IAC9C,mBAAmB;IACnB,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE;IACxC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE;IACvC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE;IACxC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE;IACtC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE;IACtC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE;IACvC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE;IACzC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE;IACtC,sBAAsB;IACtB,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE;IACrC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE;IACrC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE;IACxC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE;IACtC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE;IACxC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE;IACrC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE;IACrC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE;IACrC,cAAc;IACd,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;IAClC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE;IACnC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE;IACnC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE;IACpC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE;IACnC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;IAClC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE;CACpC,CAAC"}
@@ -0,0 +1,21 @@
1
+ export type { MatcherResult, EmbedFn, Tone, ToneScores, Sentiment, OutputFormat, PIIPattern, ToxicWord, PIIMatch, AIAssertionOptions, } from './types';
2
+ export { cosineSimilarity } from './utils/cosine-similarity';
3
+ export { tokenize } from './utils/tokenizer';
4
+ export { splitSentences } from './utils/sentences';
5
+ export { extractNgrams } from './utils/ngrams';
6
+ export { escapeRegex } from './utils/regex-escape';
7
+ export { luhnCheck } from './utils/luhn';
8
+ export { extractJSONFromCodeFence } from './utils/json-extract';
9
+ export { createCachedEmbedFn } from './utils/embedding-cache';
10
+ export { DEFAULT_PII_PATTERNS } from './catalogs/pii-patterns';
11
+ export { DEFAULT_TOXIC_WORDS } from './catalogs/toxic-words';
12
+ export { DEFAULT_HEDGING_PHRASES, DEFAULT_REFUSAL_PHRASES, DEFAULT_SYSTEM_PROMPT_PATTERNS, } from './catalogs/hedging-phrases';
13
+ export { setupAIAssertions, getGlobalOptions } from './setup';
14
+ export { toStartWith, toEndWith, toBeFormattedAs, toHaveListItems } from './matchers/format';
15
+ export { toContainAllOf, toContainAnyOf, toNotContain, toMentionEntity } from './matchers/content';
16
+ export { toHaveSentiment, toHaveTone, toBeConcise, toNotBeVerbose } from './matchers/tone';
17
+ export { toBeValidJSON, toMatchSchema, toHaveJSONFields, toBeValidMarkdown, toContainCodeBlock, } from './matchers/structural';
18
+ export { toNotContainPII, toNotContainToxicContent, toNotLeakSystemPrompt, toNotBeRefusal, } from './matchers/safety';
19
+ export { toNotBeTruncated, toNotBeHedged, toBeCompleteJSON, toNotRepeat } from './matchers/quality';
20
+ export { toBeSemanticallySimilarTo, toAnswerQuestion, toBeFactuallyConsistentWith, } from './matchers/semantic';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,aAAa,EACb,OAAO,EACP,IAAI,EACJ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,SAAS,EACT,QAAQ,EACR,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,8BAA8B,GAC/B,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAG7F,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGnG,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAG3F,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,qBAAqB,EACrB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGpG,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toBeFactuallyConsistentWith = exports.toAnswerQuestion = exports.toBeSemanticallySimilarTo = exports.toNotRepeat = exports.toBeCompleteJSON = exports.toNotBeHedged = exports.toNotBeTruncated = exports.toNotBeRefusal = exports.toNotLeakSystemPrompt = exports.toNotContainToxicContent = exports.toNotContainPII = exports.toContainCodeBlock = exports.toBeValidMarkdown = exports.toHaveJSONFields = exports.toMatchSchema = exports.toBeValidJSON = exports.toNotBeVerbose = exports.toBeConcise = exports.toHaveTone = exports.toHaveSentiment = exports.toMentionEntity = exports.toNotContain = exports.toContainAnyOf = exports.toContainAllOf = exports.toHaveListItems = exports.toBeFormattedAs = exports.toEndWith = exports.toStartWith = exports.getGlobalOptions = exports.setupAIAssertions = exports.DEFAULT_SYSTEM_PROMPT_PATTERNS = exports.DEFAULT_REFUSAL_PHRASES = exports.DEFAULT_HEDGING_PHRASES = exports.DEFAULT_TOXIC_WORDS = exports.DEFAULT_PII_PATTERNS = exports.createCachedEmbedFn = exports.extractJSONFromCodeFence = exports.luhnCheck = exports.escapeRegex = exports.extractNgrams = exports.splitSentences = exports.tokenize = exports.cosineSimilarity = void 0;
4
+ // Utilities
5
+ var cosine_similarity_1 = require("./utils/cosine-similarity");
6
+ Object.defineProperty(exports, "cosineSimilarity", { enumerable: true, get: function () { return cosine_similarity_1.cosineSimilarity; } });
7
+ var tokenizer_1 = require("./utils/tokenizer");
8
+ Object.defineProperty(exports, "tokenize", { enumerable: true, get: function () { return tokenizer_1.tokenize; } });
9
+ var sentences_1 = require("./utils/sentences");
10
+ Object.defineProperty(exports, "splitSentences", { enumerable: true, get: function () { return sentences_1.splitSentences; } });
11
+ var ngrams_1 = require("./utils/ngrams");
12
+ Object.defineProperty(exports, "extractNgrams", { enumerable: true, get: function () { return ngrams_1.extractNgrams; } });
13
+ var regex_escape_1 = require("./utils/regex-escape");
14
+ Object.defineProperty(exports, "escapeRegex", { enumerable: true, get: function () { return regex_escape_1.escapeRegex; } });
15
+ var luhn_1 = require("./utils/luhn");
16
+ Object.defineProperty(exports, "luhnCheck", { enumerable: true, get: function () { return luhn_1.luhnCheck; } });
17
+ var json_extract_1 = require("./utils/json-extract");
18
+ Object.defineProperty(exports, "extractJSONFromCodeFence", { enumerable: true, get: function () { return json_extract_1.extractJSONFromCodeFence; } });
19
+ var embedding_cache_1 = require("./utils/embedding-cache");
20
+ Object.defineProperty(exports, "createCachedEmbedFn", { enumerable: true, get: function () { return embedding_cache_1.createCachedEmbedFn; } });
21
+ // Catalogs
22
+ var pii_patterns_1 = require("./catalogs/pii-patterns");
23
+ Object.defineProperty(exports, "DEFAULT_PII_PATTERNS", { enumerable: true, get: function () { return pii_patterns_1.DEFAULT_PII_PATTERNS; } });
24
+ var toxic_words_1 = require("./catalogs/toxic-words");
25
+ Object.defineProperty(exports, "DEFAULT_TOXIC_WORDS", { enumerable: true, get: function () { return toxic_words_1.DEFAULT_TOXIC_WORDS; } });
26
+ var hedging_phrases_1 = require("./catalogs/hedging-phrases");
27
+ Object.defineProperty(exports, "DEFAULT_HEDGING_PHRASES", { enumerable: true, get: function () { return hedging_phrases_1.DEFAULT_HEDGING_PHRASES; } });
28
+ Object.defineProperty(exports, "DEFAULT_REFUSAL_PHRASES", { enumerable: true, get: function () { return hedging_phrases_1.DEFAULT_REFUSAL_PHRASES; } });
29
+ Object.defineProperty(exports, "DEFAULT_SYSTEM_PROMPT_PATTERNS", { enumerable: true, get: function () { return hedging_phrases_1.DEFAULT_SYSTEM_PROMPT_PATTERNS; } });
30
+ // Setup
31
+ var setup_1 = require("./setup");
32
+ Object.defineProperty(exports, "setupAIAssertions", { enumerable: true, get: function () { return setup_1.setupAIAssertions; } });
33
+ Object.defineProperty(exports, "getGlobalOptions", { enumerable: true, get: function () { return setup_1.getGlobalOptions; } });
34
+ // Format matchers
35
+ var format_1 = require("./matchers/format");
36
+ Object.defineProperty(exports, "toStartWith", { enumerable: true, get: function () { return format_1.toStartWith; } });
37
+ Object.defineProperty(exports, "toEndWith", { enumerable: true, get: function () { return format_1.toEndWith; } });
38
+ Object.defineProperty(exports, "toBeFormattedAs", { enumerable: true, get: function () { return format_1.toBeFormattedAs; } });
39
+ Object.defineProperty(exports, "toHaveListItems", { enumerable: true, get: function () { return format_1.toHaveListItems; } });
40
+ // Content matchers
41
+ var content_1 = require("./matchers/content");
42
+ Object.defineProperty(exports, "toContainAllOf", { enumerable: true, get: function () { return content_1.toContainAllOf; } });
43
+ Object.defineProperty(exports, "toContainAnyOf", { enumerable: true, get: function () { return content_1.toContainAnyOf; } });
44
+ Object.defineProperty(exports, "toNotContain", { enumerable: true, get: function () { return content_1.toNotContain; } });
45
+ Object.defineProperty(exports, "toMentionEntity", { enumerable: true, get: function () { return content_1.toMentionEntity; } });
46
+ // Tone matchers
47
+ var tone_1 = require("./matchers/tone");
48
+ Object.defineProperty(exports, "toHaveSentiment", { enumerable: true, get: function () { return tone_1.toHaveSentiment; } });
49
+ Object.defineProperty(exports, "toHaveTone", { enumerable: true, get: function () { return tone_1.toHaveTone; } });
50
+ Object.defineProperty(exports, "toBeConcise", { enumerable: true, get: function () { return tone_1.toBeConcise; } });
51
+ Object.defineProperty(exports, "toNotBeVerbose", { enumerable: true, get: function () { return tone_1.toNotBeVerbose; } });
52
+ // Structural matchers
53
+ var structural_1 = require("./matchers/structural");
54
+ Object.defineProperty(exports, "toBeValidJSON", { enumerable: true, get: function () { return structural_1.toBeValidJSON; } });
55
+ Object.defineProperty(exports, "toMatchSchema", { enumerable: true, get: function () { return structural_1.toMatchSchema; } });
56
+ Object.defineProperty(exports, "toHaveJSONFields", { enumerable: true, get: function () { return structural_1.toHaveJSONFields; } });
57
+ Object.defineProperty(exports, "toBeValidMarkdown", { enumerable: true, get: function () { return structural_1.toBeValidMarkdown; } });
58
+ Object.defineProperty(exports, "toContainCodeBlock", { enumerable: true, get: function () { return structural_1.toContainCodeBlock; } });
59
+ // Safety matchers
60
+ var safety_1 = require("./matchers/safety");
61
+ Object.defineProperty(exports, "toNotContainPII", { enumerable: true, get: function () { return safety_1.toNotContainPII; } });
62
+ Object.defineProperty(exports, "toNotContainToxicContent", { enumerable: true, get: function () { return safety_1.toNotContainToxicContent; } });
63
+ Object.defineProperty(exports, "toNotLeakSystemPrompt", { enumerable: true, get: function () { return safety_1.toNotLeakSystemPrompt; } });
64
+ Object.defineProperty(exports, "toNotBeRefusal", { enumerable: true, get: function () { return safety_1.toNotBeRefusal; } });
65
+ // Quality matchers
66
+ var quality_1 = require("./matchers/quality");
67
+ Object.defineProperty(exports, "toNotBeTruncated", { enumerable: true, get: function () { return quality_1.toNotBeTruncated; } });
68
+ Object.defineProperty(exports, "toNotBeHedged", { enumerable: true, get: function () { return quality_1.toNotBeHedged; } });
69
+ Object.defineProperty(exports, "toBeCompleteJSON", { enumerable: true, get: function () { return quality_1.toBeCompleteJSON; } });
70
+ Object.defineProperty(exports, "toNotRepeat", { enumerable: true, get: function () { return quality_1.toNotRepeat; } });
71
+ // Semantic matchers
72
+ var semantic_1 = require("./matchers/semantic");
73
+ Object.defineProperty(exports, "toBeSemanticallySimilarTo", { enumerable: true, get: function () { return semantic_1.toBeSemanticallySimilarTo; } });
74
+ Object.defineProperty(exports, "toAnswerQuestion", { enumerable: true, get: function () { return semantic_1.toAnswerQuestion; } });
75
+ Object.defineProperty(exports, "toBeFactuallyConsistentWith", { enumerable: true, get: function () { return semantic_1.toBeFactuallyConsistentWith; } });
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAcA,YAAY;AACZ,+DAA6D;AAApD,qHAAA,gBAAgB,OAAA;AACzB,+CAA6C;AAApC,qGAAA,QAAQ,OAAA;AACjB,+CAAmD;AAA1C,2GAAA,cAAc,OAAA;AACvB,yCAA+C;AAAtC,uGAAA,aAAa,OAAA;AACtB,qDAAmD;AAA1C,2GAAA,WAAW,OAAA;AACpB,qCAAyC;AAAhC,iGAAA,SAAS,OAAA;AAClB,qDAAgE;AAAvD,wHAAA,wBAAwB,OAAA;AACjC,2DAA8D;AAArD,sHAAA,mBAAmB,OAAA;AAE5B,WAAW;AACX,wDAA+D;AAAtD,oHAAA,oBAAoB,OAAA;AAC7B,sDAA6D;AAApD,kHAAA,mBAAmB,OAAA;AAC5B,8DAIoC;AAHlC,0HAAA,uBAAuB,OAAA;AACvB,0HAAA,uBAAuB,OAAA;AACvB,iIAAA,8BAA8B,OAAA;AAGhC,QAAQ;AACR,iCAA8D;AAArD,0GAAA,iBAAiB,OAAA;AAAE,yGAAA,gBAAgB,OAAA;AAE5C,kBAAkB;AAClB,4CAA6F;AAApF,qGAAA,WAAW,OAAA;AAAE,mGAAA,SAAS,OAAA;AAAE,yGAAA,eAAe,OAAA;AAAE,yGAAA,eAAe,OAAA;AAEjE,mBAAmB;AACnB,8CAAmG;AAA1F,yGAAA,cAAc,OAAA;AAAE,yGAAA,cAAc,OAAA;AAAE,uGAAA,YAAY,OAAA;AAAE,0GAAA,eAAe,OAAA;AAEtE,gBAAgB;AAChB,wCAA2F;AAAlF,uGAAA,eAAe,OAAA;AAAE,kGAAA,UAAU,OAAA;AAAE,mGAAA,WAAW,OAAA;AAAE,sGAAA,cAAc,OAAA;AAEjE,sBAAsB;AACtB,oDAM+B;AAL7B,2GAAA,aAAa,OAAA;AACb,2GAAA,aAAa,OAAA;AACb,8GAAA,gBAAgB,OAAA;AAChB,+GAAA,iBAAiB,OAAA;AACjB,gHAAA,kBAAkB,OAAA;AAGpB,kBAAkB;AAClB,4CAK2B;AAJzB,yGAAA,eAAe,OAAA;AACf,kHAAA,wBAAwB,OAAA;AACxB,+GAAA,qBAAqB,OAAA;AACrB,wGAAA,cAAc,OAAA;AAGhB,mBAAmB;AACnB,8CAAoG;AAA3F,2GAAA,gBAAgB,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,sGAAA,WAAW,OAAA;AAEvE,oBAAoB;AACpB,gDAI6B;AAH3B,qHAAA,yBAAyB,OAAA;AACzB,4GAAA,gBAAgB,OAAA;AAChB,uHAAA,2BAA2B,OAAA"}
@@ -0,0 +1,6 @@
1
+ import type { MatcherResult } from '../types';
2
+ export declare function toContainAllOf(received: string, phrases: string[]): MatcherResult;
3
+ export declare function toContainAnyOf(received: string, phrases: string[]): MatcherResult;
4
+ export declare function toNotContain(received: string, phrase: string): MatcherResult;
5
+ export declare function toMentionEntity(received: string, entity: string, aliases?: string[]): MatcherResult;
6
+ //# sourceMappingURL=content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/matchers/content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,aAAa,CAYjF;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,aAAa,CAYjF;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAU5E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,aAAa,CAanG"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toContainAllOf = toContainAllOf;
4
+ exports.toContainAnyOf = toContainAnyOf;
5
+ exports.toNotContain = toNotContain;
6
+ exports.toMentionEntity = toMentionEntity;
7
+ function toContainAllOf(received, phrases) {
8
+ const lower = received.toLowerCase();
9
+ const missing = phrases.filter((p) => !lower.includes(p.toLowerCase()));
10
+ const pass = missing.length === 0;
11
+ return {
12
+ pass,
13
+ message: () => pass
14
+ ? `Expected output not to contain all of: ${phrases.join(', ')}`
15
+ : `Expected output to contain all of: ${phrases.join(', ')}, but missing: ${missing.join(', ')}`,
16
+ details: { phrases, missing },
17
+ };
18
+ }
19
+ function toContainAnyOf(received, phrases) {
20
+ const lower = received.toLowerCase();
21
+ const found = phrases.filter((p) => lower.includes(p.toLowerCase()));
22
+ const pass = found.length > 0;
23
+ return {
24
+ pass,
25
+ message: () => pass
26
+ ? `Expected output not to contain any of: ${phrases.join(', ')}`
27
+ : `Expected output to contain at least one of: ${phrases.join(', ')}, but none were found`,
28
+ details: { phrases, found },
29
+ };
30
+ }
31
+ function toNotContain(received, phrase) {
32
+ const pass = !received.toLowerCase().includes(phrase.toLowerCase());
33
+ return {
34
+ pass,
35
+ message: () => pass
36
+ ? `Expected output to contain "${phrase}", but it did not`
37
+ : `Expected output not to contain "${phrase}", but it was found`,
38
+ details: { phrase, found: !pass },
39
+ };
40
+ }
41
+ function toMentionEntity(received, entity, aliases) {
42
+ const lower = received.toLowerCase();
43
+ const terms = [entity, ...(aliases ?? [])];
44
+ const found = terms.find((t) => lower.includes(t.toLowerCase()));
45
+ const pass = found !== undefined;
46
+ return {
47
+ pass,
48
+ message: () => pass
49
+ ? `Expected output not to mention "${entity}" (or aliases)`
50
+ : `Expected output to mention "${entity}"${aliases?.length ? ` or aliases [${aliases.join(', ')}]` : ''}, but none were found`,
51
+ details: { entity, aliases, foundTerm: found ?? null },
52
+ };
53
+ }
54
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/matchers/content.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { MatcherResult, OutputFormat } from '../types';
2
+ export declare function toStartWith(received: string, prefix: string): MatcherResult;
3
+ export declare function toEndWith(received: string, suffix: string): MatcherResult;
4
+ export declare function toBeFormattedAs(received: string, format: OutputFormat): MatcherResult;
5
+ export declare function toHaveListItems(received: string, items: string[]): MatcherResult;
6
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/matchers/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE5D,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAU3E;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAUzE;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,aAAa,CAsErF;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,aAAa,CAmBhF"}
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toStartWith = toStartWith;
4
+ exports.toEndWith = toEndWith;
5
+ exports.toBeFormattedAs = toBeFormattedAs;
6
+ exports.toHaveListItems = toHaveListItems;
7
+ function toStartWith(received, prefix) {
8
+ const pass = received.startsWith(prefix);
9
+ return {
10
+ pass,
11
+ message: () => pass
12
+ ? `Expected string not to start with "${prefix}"`
13
+ : `Expected string to start with "${prefix}", but got "${received.slice(0, 50)}"`,
14
+ details: { prefix, receivedStart: received.slice(0, prefix.length) },
15
+ };
16
+ }
17
+ function toEndWith(received, suffix) {
18
+ const pass = received.endsWith(suffix);
19
+ return {
20
+ pass,
21
+ message: () => pass
22
+ ? `Expected string not to end with "${suffix}"`
23
+ : `Expected string to end with "${suffix}", but got "...${received.slice(-50)}"`,
24
+ details: { suffix, receivedEnd: received.slice(-suffix.length) },
25
+ };
26
+ }
27
+ function toBeFormattedAs(received, format) {
28
+ let pass = false;
29
+ let reason = '';
30
+ switch (format) {
31
+ case 'json': {
32
+ const text = received.trim();
33
+ try {
34
+ JSON.parse(text);
35
+ pass = true;
36
+ }
37
+ catch (e) {
38
+ reason = e.message;
39
+ }
40
+ break;
41
+ }
42
+ case 'markdown': {
43
+ const hasHeading = /^#{1,6}\s/m.test(received);
44
+ const hasBold = /\*\*[^*]+\*\*/.test(received);
45
+ const hasItalic = /\*[^*]+\*/.test(received);
46
+ const hasCodeFence = /```/.test(received);
47
+ const hasList = /^[-*]\s|^\d+\.\s/m.test(received);
48
+ const hasBlockquote = /^>\s/m.test(received);
49
+ pass = hasHeading || hasBold || hasItalic || hasCodeFence || hasList || hasBlockquote;
50
+ if (!pass)
51
+ reason = 'No markdown patterns detected (headings, bold, code, lists, blockquotes)';
52
+ break;
53
+ }
54
+ case 'list': {
55
+ const lines = received.split('\n').filter((l) => l.trim().length > 0);
56
+ const listLines = lines.filter((l) => /^\s*[-*]\s|^\s*\d+[.)]\s/.test(l));
57
+ pass = lines.length > 0 && listLines.length / lines.length >= 0.5;
58
+ if (!pass)
59
+ reason = `Only ${listLines.length}/${lines.length} lines are list items`;
60
+ break;
61
+ }
62
+ case 'csv': {
63
+ const lines = received.trim().split('\n').filter((l) => l.trim().length > 0);
64
+ if (lines.length >= 2) {
65
+ const colCounts = lines.map((l) => l.split(',').length);
66
+ const first = colCounts[0];
67
+ pass = first >= 2 && colCounts.every((c) => c === first);
68
+ }
69
+ if (!pass)
70
+ reason = 'CSV requires consistent comma-separated columns across all lines';
71
+ break;
72
+ }
73
+ case 'xml': {
74
+ pass = /<[a-zA-Z][^>]*>[\s\S]*<\/[a-zA-Z][^>]*>/.test(received);
75
+ if (!pass)
76
+ reason = 'No XML tag pairs detected';
77
+ break;
78
+ }
79
+ case 'yaml': {
80
+ const lines = received.trim().split('\n').filter((l) => l.trim().length > 0 && !l.trim().startsWith('#'));
81
+ const keyValueLines = lines.filter((l) => /^\s*[\w-]+\s*:/.test(l));
82
+ pass = lines.length > 0 && keyValueLines.length / lines.length >= 0.5;
83
+ if (!pass)
84
+ reason = 'Fewer than 50% of lines match YAML key: value pattern';
85
+ break;
86
+ }
87
+ case 'table': {
88
+ pass = /\|[^|]+\|/.test(received) && received.includes('|');
89
+ if (!pass)
90
+ reason = 'No table pipe (|) patterns detected';
91
+ break;
92
+ }
93
+ }
94
+ return {
95
+ pass,
96
+ message: () => pass
97
+ ? `Expected output not to be formatted as ${format}`
98
+ : `Expected output to be formatted as ${format}${reason ? ': ' + reason : ''}`,
99
+ details: { format, reason },
100
+ };
101
+ }
102
+ function toHaveListItems(received, items) {
103
+ const missing = [];
104
+ for (const item of items) {
105
+ // Item must appear on a line that starts with a bullet or number
106
+ const escaped = item.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
107
+ const pattern = new RegExp(`^\\s*(?:[-*]|\\d+[.)])\\s+.*${escaped}`, 'm');
108
+ if (!pattern.test(received)) {
109
+ missing.push(item);
110
+ }
111
+ }
112
+ const pass = missing.length === 0;
113
+ return {
114
+ pass,
115
+ message: () => pass
116
+ ? `Expected output not to have all list items: ${items.join(', ')}`
117
+ : `Expected output to have list items, but missing: ${missing.join(', ')}`,
118
+ details: { items, missing },
119
+ };
120
+ }
121
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/matchers/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { MatcherResult } from '../types';
2
+ export declare function toNotBeTruncated(received: string): MatcherResult;
3
+ export declare function toNotBeHedged(received: string, phrases?: string[], threshold?: number): MatcherResult;
4
+ export declare function toBeCompleteJSON(received: string): MatcherResult;
5
+ export declare function toNotRepeat(received: string, options?: {
6
+ windowSize?: number;
7
+ threshold?: number;
8
+ }): MatcherResult;
9
+ //# sourceMappingURL=quality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../src/matchers/quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAM9C,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CA8BhE;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAAE,EAClB,SAAS,SAAM,GACd,aAAa,CAuBf;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CA0BhE;AAED,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACxD,aAAa,CAwBf"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toNotBeTruncated = toNotBeTruncated;
4
+ exports.toNotBeHedged = toNotBeHedged;
5
+ exports.toBeCompleteJSON = toBeCompleteJSON;
6
+ exports.toNotRepeat = toNotRepeat;
7
+ const tokenizer_1 = require("../utils/tokenizer");
8
+ const sentences_1 = require("../utils/sentences");
9
+ const ngrams_1 = require("../utils/ngrams");
10
+ const hedging_phrases_1 = require("../catalogs/hedging-phrases");
11
+ function toNotBeTruncated(received) {
12
+ const issues = [];
13
+ const trimmed = received.trim();
14
+ // Check ends with sentence-terminal punctuation
15
+ if (trimmed.length > 0 && !/[.!?'")\]>]$/.test(trimmed)) {
16
+ issues.push('Does not end with terminal punctuation');
17
+ }
18
+ // Check for unclosed code fences
19
+ const codeFences = (trimmed.match(/```/g) ?? []).length;
20
+ if (codeFences % 2 !== 0) {
21
+ issues.push('Unclosed code fence');
22
+ }
23
+ // Check for hanging list items (list item with no content after bullet)
24
+ const hangingList = /^[-*]\s*$|^\d+[.)]\s*$/m.test(trimmed);
25
+ if (hangingList) {
26
+ issues.push('Hanging list item with no content');
27
+ }
28
+ const pass = issues.length === 0;
29
+ return {
30
+ pass,
31
+ message: () => pass
32
+ ? `Expected output to appear truncated, but it looks complete`
33
+ : `Expected output not to be truncated, but found issues: ${issues.join('; ')}`,
34
+ details: { issues },
35
+ };
36
+ }
37
+ function toNotBeHedged(received, phrases, threshold = 0.3) {
38
+ const allPhrases = [...hedging_phrases_1.DEFAULT_HEDGING_PHRASES, ...(phrases ?? [])];
39
+ const lower = received.toLowerCase();
40
+ const sentences = (0, sentences_1.splitSentences)(received);
41
+ const sentenceCount = Math.max(sentences.length, 1);
42
+ const foundPhrases = [];
43
+ for (const phrase of allPhrases) {
44
+ if (lower.includes(phrase.toLowerCase())) {
45
+ foundPhrases.push(phrase);
46
+ }
47
+ }
48
+ const ratio = foundPhrases.length / sentenceCount;
49
+ const pass = ratio < threshold;
50
+ return {
51
+ pass,
52
+ message: () => pass
53
+ ? `Expected output to be hedged, but hedging ratio ${ratio.toFixed(2)} < threshold ${threshold}`
54
+ : `Expected output not to be hedged, but hedging ratio ${ratio.toFixed(2)} >= threshold ${threshold} (phrases: ${foundPhrases.join(', ')})`,
55
+ details: { foundPhrases, ratio, threshold, sentenceCount },
56
+ };
57
+ }
58
+ function toBeCompleteJSON(received) {
59
+ const trimmed = received.trim();
60
+ try {
61
+ JSON.parse(trimmed);
62
+ return {
63
+ pass: true,
64
+ message: () => `Expected output not to be complete JSON`,
65
+ details: { complete: true },
66
+ };
67
+ }
68
+ catch (parseError) {
69
+ // Check if it looks like truncated JSON
70
+ const looksLikeJSON = trimmed.startsWith('{') || trimmed.startsWith('[');
71
+ const properlyTerminated = (trimmed.startsWith('{') && trimmed.endsWith('}')) ||
72
+ (trimmed.startsWith('[') && trimmed.endsWith(']'));
73
+ const truncated = looksLikeJSON && !properlyTerminated;
74
+ return {
75
+ pass: false,
76
+ message: () => truncated
77
+ ? `Expected output to be complete JSON, but it appears truncated (starts with ${trimmed[0]} but does not end with matching bracket)`
78
+ : `Expected output to be complete JSON, but it is not valid JSON: ${parseError.message}`,
79
+ details: { truncated, parseError: parseError.message },
80
+ };
81
+ }
82
+ }
83
+ function toNotRepeat(received, options = {}) {
84
+ const windowSize = options.windowSize ?? 4;
85
+ const threshold = options.threshold ?? 3;
86
+ const tokens = (0, tokenizer_1.tokenize)(received.toLowerCase());
87
+ const ngrams = (0, ngrams_1.extractNgrams)(tokens, windowSize);
88
+ const counts = new Map();
89
+ for (const ng of ngrams) {
90
+ counts.set(ng, (counts.get(ng) ?? 0) + 1);
91
+ }
92
+ const repeated = [];
93
+ for (const [ngram, count] of counts.entries()) {
94
+ if (count > threshold) {
95
+ repeated.push({ ngram, count });
96
+ }
97
+ }
98
+ const pass = repeated.length === 0;
99
+ return {
100
+ pass,
101
+ message: () => pass
102
+ ? `Expected output to have repetitions, but none exceeded threshold ${threshold}`
103
+ : `Expected output not to repeat, but found ${repeated.length} repeated ${windowSize}-gram(s): ${repeated.map((r) => `"${r.ngram}" (${r.count}x)`).join(', ')}`,
104
+ details: { repeated, windowSize, threshold },
105
+ };
106
+ }
107
+ //# sourceMappingURL=quality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.js","sourceRoot":"","sources":["../../src/matchers/quality.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { MatcherResult, PIIPattern, ToxicWord } from '../types';
2
+ export declare function toNotContainPII(received: string, patterns?: PIIPattern[]): MatcherResult;
3
+ export declare function toNotContainToxicContent(received: string, words?: ToxicWord[]): MatcherResult;
4
+ export declare function toNotLeakSystemPrompt(received: string, patterns?: RegExp[]): MatcherResult;
5
+ export declare function toNotBeRefusal(received: string, phrases?: string[]): MatcherResult;
6
+ //# sourceMappingURL=safety.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../src/matchers/safety.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAY,MAAM,UAAU,CAAC;AAK/E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,UAAU,EAAE,GAAG,aAAa,CA4BxF;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,aAAa,CAuB7F;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,aAAa,CAmB1F;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,aAAa,CAalF"}