promptfoo 0.95.0 → 0.96.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 (240) hide show
  1. package/README.md +2 -1
  2. package/dist/package.json +13 -11
  3. package/dist/src/app/assets/{index-zXzgAsKj.js → index-Dwt7E2K_.js} +178 -178
  4. package/dist/src/app/assets/{index.es-Jztl1qad.js → index.es-CooNf3HB.js} +1 -1
  5. package/dist/src/app/assets/{sync-BJBBGzPI.js → sync-Bj1WJrHQ.js} +1 -1
  6. package/dist/src/app/index.html +1 -1
  7. package/dist/src/assertions/bleu.d.ts +33 -0
  8. package/dist/src/assertions/bleu.d.ts.map +1 -0
  9. package/dist/src/assertions/bleu.js +116 -0
  10. package/dist/src/assertions/bleu.js.map +1 -0
  11. package/dist/src/assertions/index.d.ts +1 -12
  12. package/dist/src/assertions/index.d.ts.map +1 -1
  13. package/dist/src/assertions/index.js +20 -250
  14. package/dist/src/assertions/index.js.map +1 -1
  15. package/dist/src/assertions/json.d.ts +8 -0
  16. package/dist/src/assertions/json.d.ts.map +1 -0
  17. package/dist/src/assertions/json.js +121 -0
  18. package/dist/src/assertions/json.js.map +1 -0
  19. package/dist/src/assertions/perplexity.d.ts +4 -0
  20. package/dist/src/assertions/perplexity.d.ts.map +1 -0
  21. package/dist/src/assertions/perplexity.js +40 -0
  22. package/dist/src/assertions/perplexity.js.map +1 -0
  23. package/dist/src/assertions/sql.d.ts +4 -0
  24. package/dist/src/assertions/sql.d.ts.map +1 -0
  25. package/dist/src/assertions/sql.js +87 -0
  26. package/dist/src/assertions/sql.js.map +1 -0
  27. package/dist/src/assertions/xml.d.ts +9 -0
  28. package/dist/src/assertions/xml.d.ts.map +1 -0
  29. package/dist/src/assertions/xml.js +57 -0
  30. package/dist/src/assertions/xml.js.map +1 -0
  31. package/dist/src/commands/eval/filterTests.d.ts +1 -0
  32. package/dist/src/commands/eval/filterTests.d.ts.map +1 -1
  33. package/dist/src/commands/eval/filterTests.js +14 -1
  34. package/dist/src/commands/eval/filterTests.js.map +1 -1
  35. package/dist/src/commands/eval.d.ts.map +1 -1
  36. package/dist/src/commands/eval.js +14 -3
  37. package/dist/src/commands/eval.js.map +1 -1
  38. package/dist/src/commands/import.d.ts.map +1 -1
  39. package/dist/src/commands/import.js +1 -0
  40. package/dist/src/commands/import.js.map +1 -1
  41. package/dist/src/commands/list.d.ts.map +1 -1
  42. package/dist/src/commands/list.js +15 -0
  43. package/dist/src/commands/list.js.map +1 -1
  44. package/dist/src/csv.d.ts.map +1 -1
  45. package/dist/src/csv.js +9 -4
  46. package/dist/src/csv.js.map +1 -1
  47. package/dist/src/database/tables.d.ts +189 -1
  48. package/dist/src/database/tables.d.ts.map +1 -1
  49. package/dist/src/envars.d.ts +9 -0
  50. package/dist/src/envars.d.ts.map +1 -1
  51. package/dist/src/envars.js.map +1 -1
  52. package/dist/src/evaluator.js +2 -2
  53. package/dist/src/evaluator.js.map +1 -1
  54. package/dist/src/evaluatorHelpers.d.ts.map +1 -1
  55. package/dist/src/evaluatorHelpers.js +4 -0
  56. package/dist/src/evaluatorHelpers.js.map +1 -1
  57. package/dist/src/globalConfig/accounts.d.ts +1 -0
  58. package/dist/src/globalConfig/accounts.d.ts.map +1 -1
  59. package/dist/src/globalConfig/accounts.js +24 -0
  60. package/dist/src/globalConfig/accounts.js.map +1 -1
  61. package/dist/src/index.d.ts +74 -68
  62. package/dist/src/index.d.ts.map +1 -1
  63. package/dist/src/onboarding.js +8 -8
  64. package/dist/src/onboarding.js.map +1 -1
  65. package/dist/src/providers/adaline.gateway.d.ts.map +1 -1
  66. package/dist/src/providers/adaline.gateway.js +4 -4
  67. package/dist/src/providers/adaline.gateway.js.map +1 -1
  68. package/dist/src/providers/anthropic.d.ts.map +1 -1
  69. package/dist/src/providers/anthropic.js +21 -0
  70. package/dist/src/providers/anthropic.js.map +1 -1
  71. package/dist/src/providers/{azureopenai.d.ts → azure.d.ts} +13 -13
  72. package/dist/src/providers/azure.d.ts.map +1 -0
  73. package/dist/src/providers/{azureopenai.js → azure.js} +64 -42
  74. package/dist/src/providers/azure.js.map +1 -0
  75. package/dist/src/providers/{azureopenaiUtil.d.ts → azureUtil.d.ts} +1 -1
  76. package/dist/src/providers/azureUtil.d.ts.map +1 -0
  77. package/dist/src/providers/{azureopenaiUtil.js → azureUtil.js} +3 -3
  78. package/dist/src/providers/azureUtil.js.map +1 -0
  79. package/dist/src/providers/bedrock.d.ts +5 -3
  80. package/dist/src/providers/bedrock.d.ts.map +1 -1
  81. package/dist/src/providers/bedrock.js +37 -8
  82. package/dist/src/providers/bedrock.js.map +1 -1
  83. package/dist/src/providers/defaults.d.ts.map +1 -1
  84. package/dist/src/providers/defaults.js +36 -0
  85. package/dist/src/providers/defaults.js.map +1 -1
  86. package/dist/src/providers/portkey.d.ts +3 -2
  87. package/dist/src/providers/portkey.d.ts.map +1 -1
  88. package/dist/src/providers/portkey.js +17 -10
  89. package/dist/src/providers/portkey.js.map +1 -1
  90. package/dist/src/providers/promptfoo.js +2 -2
  91. package/dist/src/providers/promptfoo.js.map +1 -1
  92. package/dist/src/providers.d.ts +9 -5
  93. package/dist/src/providers.d.ts.map +1 -1
  94. package/dist/src/providers.js +16 -11
  95. package/dist/src/providers.js.map +1 -1
  96. package/dist/src/redteam/commands/generate.d.ts.map +1 -1
  97. package/dist/src/redteam/commands/generate.js +5 -1
  98. package/dist/src/redteam/commands/generate.js.map +1 -1
  99. package/dist/src/redteam/commands/init.d.ts +11 -0
  100. package/dist/src/redteam/commands/init.d.ts.map +1 -1
  101. package/dist/src/redteam/commands/init.js +47 -12
  102. package/dist/src/redteam/commands/init.js.map +1 -1
  103. package/dist/src/redteam/commands/poison.d.ts +3 -0
  104. package/dist/src/redteam/commands/poison.d.ts.map +1 -0
  105. package/dist/src/redteam/commands/poison.js +165 -0
  106. package/dist/src/redteam/commands/poison.js.map +1 -0
  107. package/dist/src/redteam/commands/run.d.ts.map +1 -1
  108. package/dist/src/redteam/commands/run.js +2 -0
  109. package/dist/src/redteam/commands/run.js.map +1 -1
  110. package/dist/src/redteam/constants.d.ts +2 -2
  111. package/dist/src/redteam/constants.d.ts.map +1 -1
  112. package/dist/src/redteam/constants.js +13 -4
  113. package/dist/src/redteam/constants.js.map +1 -1
  114. package/dist/src/redteam/extraction/util.js +1 -1
  115. package/dist/src/redteam/extraction/util.js.map +1 -1
  116. package/dist/src/redteam/graders.d.ts +34 -32
  117. package/dist/src/redteam/graders.d.ts.map +1 -1
  118. package/dist/src/redteam/graders.js +34 -33
  119. package/dist/src/redteam/graders.js.map +1 -1
  120. package/dist/src/redteam/index.d.ts.map +1 -1
  121. package/dist/src/redteam/index.js +9 -2
  122. package/dist/src/redteam/index.js.map +1 -1
  123. package/dist/src/redteam/plugins/bfla.d.ts.map +1 -1
  124. package/dist/src/redteam/plugins/bfla.js +5 -3
  125. package/dist/src/redteam/plugins/bfla.js.map +1 -1
  126. package/dist/src/redteam/plugins/bola.js +3 -3
  127. package/dist/src/redteam/plugins/index.d.ts.map +1 -1
  128. package/dist/src/redteam/plugins/index.js +3 -2
  129. package/dist/src/redteam/plugins/index.js.map +1 -1
  130. package/dist/src/redteam/plugins/intent.d.ts +22 -0
  131. package/dist/src/redteam/plugins/intent.d.ts.map +1 -0
  132. package/dist/src/redteam/plugins/intent.js +100 -0
  133. package/dist/src/redteam/plugins/intent.js.map +1 -0
  134. package/dist/src/redteam/plugins/pii.d.ts.map +1 -1
  135. package/dist/src/redteam/plugins/pii.js +21 -14
  136. package/dist/src/redteam/plugins/pii.js.map +1 -1
  137. package/dist/src/redteam/plugins/rbac.d.ts.map +1 -1
  138. package/dist/src/redteam/plugins/rbac.js +5 -4
  139. package/dist/src/redteam/plugins/rbac.js.map +1 -1
  140. package/dist/src/redteam/plugins/sqlInjection.d.ts.map +1 -1
  141. package/dist/src/redteam/plugins/sqlInjection.js +13 -4
  142. package/dist/src/redteam/plugins/sqlInjection.js.map +1 -1
  143. package/dist/src/redteam/providers/crescendo/index.d.ts.map +1 -1
  144. package/dist/src/redteam/providers/crescendo/index.js +6 -4
  145. package/dist/src/redteam/providers/crescendo/index.js.map +1 -1
  146. package/dist/src/redteam/providers/goat.js +1 -1
  147. package/dist/src/redteam/providers/goat.js.map +1 -1
  148. package/dist/src/redteam/providers/iterative.d.ts.map +1 -1
  149. package/dist/src/redteam/providers/iterative.js +4 -2
  150. package/dist/src/redteam/providers/iterative.js.map +1 -1
  151. package/dist/src/redteam/providers/iterativeImage.d.ts.map +1 -1
  152. package/dist/src/redteam/providers/iterativeImage.js +4 -2
  153. package/dist/src/redteam/providers/iterativeImage.js.map +1 -1
  154. package/dist/src/redteam/providers/iterativeTree.d.ts +3 -1
  155. package/dist/src/redteam/providers/iterativeTree.d.ts.map +1 -1
  156. package/dist/src/redteam/providers/iterativeTree.js +5 -3
  157. package/dist/src/redteam/providers/iterativeTree.js.map +1 -1
  158. package/dist/src/redteam/providers/shared.d.ts +2 -2
  159. package/dist/src/redteam/providers/shared.d.ts.map +1 -1
  160. package/dist/src/redteam/providers/shared.js +2 -2
  161. package/dist/src/redteam/providers/shared.js.map +1 -1
  162. package/dist/src/redteam/strategies/mathPrompt.js +1 -1
  163. package/dist/src/redteam/strategies/mathPrompt.js.map +1 -1
  164. package/dist/src/redteam/strategies/multilingual.js +1 -1
  165. package/dist/src/redteam/strategies/multilingual.js.map +1 -1
  166. package/dist/src/redteam/types.d.ts +1 -0
  167. package/dist/src/redteam/types.d.ts.map +1 -1
  168. package/dist/src/remoteGrading.js +1 -1
  169. package/dist/src/remoteGrading.js.map +1 -1
  170. package/dist/src/telemetry.d.ts +2 -2
  171. package/dist/src/types/index.d.ts +4630 -11
  172. package/dist/src/types/index.d.ts.map +1 -1
  173. package/dist/src/types/index.js +2 -0
  174. package/dist/src/types/index.js.map +1 -1
  175. package/dist/src/types/providers.d.ts +12 -0
  176. package/dist/src/types/providers.d.ts.map +1 -1
  177. package/dist/src/types/providers.js.map +1 -1
  178. package/dist/src/util/config/load.d.ts +1 -1
  179. package/dist/src/util/config/load.d.ts.map +1 -1
  180. package/dist/src/util/config/load.js +14 -2
  181. package/dist/src/util/config/load.js.map +1 -1
  182. package/dist/src/util/index.d.ts +34 -0
  183. package/dist/src/util/index.d.ts.map +1 -1
  184. package/dist/src/validators/providers.d.ts +391 -0
  185. package/dist/src/validators/providers.d.ts.map +1 -1
  186. package/dist/src/validators/providers.js +18 -0
  187. package/dist/src/validators/providers.js.map +1 -1
  188. package/dist/src/validators/redteam.d.ts +136 -0
  189. package/dist/src/validators/redteam.d.ts.map +1 -1
  190. package/dist/test/assertions/bleu.test.d.ts +2 -0
  191. package/dist/test/assertions/bleu.test.d.ts.map +1 -0
  192. package/dist/test/assertions/bleu.test.js +137 -0
  193. package/dist/test/assertions/bleu.test.js.map +1 -0
  194. package/dist/test/assertions/index.test.js +276 -297
  195. package/dist/test/assertions/index.test.js.map +1 -1
  196. package/dist/test/assertions/json.test.d.ts +2 -0
  197. package/dist/test/assertions/json.test.d.ts.map +1 -0
  198. package/dist/test/assertions/json.test.js +36 -0
  199. package/dist/test/assertions/json.test.js.map +1 -0
  200. package/dist/test/assertions/sql.test.d.ts +2 -0
  201. package/dist/test/assertions/sql.test.d.ts.map +1 -0
  202. package/dist/test/{is-sql-tests/node-sql-parser.test.js → assertions/sql.test.js} +13 -13
  203. package/dist/test/assertions/sql.test.js.map +1 -0
  204. package/dist/test/commands/eval/filterTests.test.js +30 -0
  205. package/dist/test/commands/eval/filterTests.test.js.map +1 -1
  206. package/dist/test/factories/evalFactory.d.ts +155 -1
  207. package/dist/test/factories/evalFactory.d.ts.map +1 -1
  208. package/dist/test/onboarding.test.js +126 -1
  209. package/dist/test/onboarding.test.js.map +1 -1
  210. package/dist/test/providers/anthropic.test.js +81 -0
  211. package/dist/test/providers/anthropic.test.js.map +1 -1
  212. package/dist/test/providers/azure.test.js +22 -25
  213. package/dist/test/providers/azure.test.js.map +1 -1
  214. package/dist/test/providers/bedrock.test.js +178 -55
  215. package/dist/test/providers/bedrock.test.js.map +1 -1
  216. package/dist/test/providers/index.test.js +7 -7
  217. package/dist/test/providers/index.test.js.map +1 -1
  218. package/dist/test/providers/portkey.test.d.ts +2 -0
  219. package/dist/test/providers/portkey.test.d.ts.map +1 -0
  220. package/dist/test/providers/portkey.test.js +46 -0
  221. package/dist/test/providers/portkey.test.js.map +1 -0
  222. package/dist/test/redteam/commands/init.test.d.ts +2 -0
  223. package/dist/test/redteam/commands/init.test.d.ts.map +1 -0
  224. package/dist/test/redteam/commands/init.test.js +109 -0
  225. package/dist/test/redteam/commands/init.test.js.map +1 -0
  226. package/dist/test/redteam/plugins/pluginDocumentation.test.js +4 -1
  227. package/dist/test/redteam/plugins/pluginDocumentation.test.js.map +1 -1
  228. package/dist/test/redteam/providers/goat.test.js +1 -1
  229. package/dist/test/redteam/providers/goat.test.js.map +1 -1
  230. package/dist/test/redteam/providers/iterativeTree.test.js +8 -3
  231. package/dist/test/redteam/providers/iterativeTree.test.js.map +1 -1
  232. package/dist/tsconfig.tsbuildinfo +1 -1
  233. package/package.json +13 -11
  234. package/dist/src/providers/azureopenai.d.ts.map +0 -1
  235. package/dist/src/providers/azureopenai.js.map +0 -1
  236. package/dist/src/providers/azureopenaiUtil.d.ts.map +0 -1
  237. package/dist/src/providers/azureopenaiUtil.js.map +0 -1
  238. package/dist/test/is-sql-tests/node-sql-parser.test.d.ts +0 -2
  239. package/dist/test/is-sql-tests/node-sql-parser.test.d.ts.map +0 -1
  240. package/dist/test/is-sql-tests/node-sql-parser.test.js.map +0 -1
@@ -31,6 +31,7 @@ const fs = __importStar(require("fs"));
31
31
  const node_module_1 = require("node:module");
32
32
  const path = __importStar(require("path"));
33
33
  const assertions_1 = require("../../src/assertions");
34
+ const xml_1 = require("../../src/assertions/xml");
34
35
  const fetch_1 = require("../../src/fetch");
35
36
  const openai_1 = require("../../src/providers/openai");
36
37
  const replicate_1 = require("../../src/providers/replicate");
@@ -103,30 +104,6 @@ jest.mock('../../src/matchers', () => {
103
104
  };
104
105
  });
105
106
  const Grader = new utils_1.TestGrader();
106
- describe('createAjv', () => {
107
- beforeAll(() => {
108
- delete process.env.PROMPTFOO_DISABLE_AJV_STRICT_MODE;
109
- jest.resetModules();
110
- });
111
- afterAll(() => {
112
- delete process.env.PROMPTFOO_DISABLE_AJV_STRICT_MODE;
113
- });
114
- it('should create an Ajv instance with default options', () => {
115
- const ajv = (0, assertions_1.createAjv)();
116
- expect(ajv).toBeDefined();
117
- expect(ajv.opts.strictSchema).toBe(true);
118
- });
119
- it('should disable strict mode when PROMPTFOO_DISABLE_AJV_STRICT_MODE is set', () => {
120
- process.env.PROMPTFOO_DISABLE_AJV_STRICT_MODE = 'true';
121
- const ajv = (0, assertions_1.createAjv)();
122
- expect(ajv.opts.strictSchema).toBe(false);
123
- });
124
- it('should add formats to the Ajv instance', () => {
125
- const ajv = (0, assertions_1.createAjv)();
126
- expect(ajv.formats).toBeDefined();
127
- expect(Object.keys(ajv.formats)).not.toHaveLength(0);
128
- });
129
- });
130
107
  describe('runAssertions', () => {
131
108
  const test = {
132
109
  assert: [
@@ -955,278 +932,280 @@ describe('runAssertion', () => {
955
932
  reason: 'JSON does not conform to the provided schema. Errors: data/latitude must be number',
956
933
  });
957
934
  });
958
- it('should pass when the is-sql assertion passes', async () => {
959
- const output = 'SELECT id, name FROM users';
960
- const result = await (0, assertions_1.runAssertion)({
961
- prompt: 'Some prompt',
962
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
963
- assertion: isSqlAssertion,
964
- test: {},
965
- providerResponse: { output },
966
- });
967
- expect(result).toMatchObject({
968
- pass: true,
969
- reason: 'Assertion passed',
970
- });
971
- });
972
- it('should fail when the is-sql assertion fails', async () => {
973
- const output = 'SELECT * FROM orders ORDERY BY order_date';
974
- const result = await (0, assertions_1.runAssertion)({
975
- prompt: 'Some prompt',
976
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
977
- assertion: isSqlAssertion,
978
- test: {},
979
- providerResponse: { output },
980
- });
981
- expect(result).toMatchObject({
982
- pass: false,
983
- reason: 'SQL statement does not conform to the provided MySQL database syntax.',
984
- });
985
- });
986
- it('should pass when the not-is-sql assertion passes', async () => {
987
- const output = 'SELECT * FROM orders ORDERY BY order_date';
988
- const result = await (0, assertions_1.runAssertion)({
989
- prompt: 'Some prompt',
990
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
991
- assertion: notIsSqlAssertion,
992
- test: {},
993
- providerResponse: { output },
994
- });
995
- expect(result).toMatchObject({
996
- pass: true,
997
- reason: 'Assertion passed',
998
- });
999
- });
1000
- it('should fail when the not-is-sql assertion fails', async () => {
1001
- const output = 'SELECT id, name FROM users';
1002
- const result = await (0, assertions_1.runAssertion)({
1003
- prompt: 'Some prompt',
1004
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1005
- assertion: notIsSqlAssertion,
1006
- test: {},
1007
- providerResponse: { output },
1008
- });
1009
- expect(result).toMatchObject({
1010
- pass: false,
1011
- reason: 'The output SQL statement is valid',
1012
- });
1013
- });
1014
- it('should pass when the is-sql assertion passes given MySQL Database syntax', async () => {
1015
- const output = 'SELECT id, name FROM users';
1016
- const result = await (0, assertions_1.runAssertion)({
1017
- prompt: 'Some prompt',
1018
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1019
- assertion: isSqlAssertionWithDatabase,
1020
- test: {},
1021
- providerResponse: { output },
1022
- });
1023
- expect(result).toMatchObject({
1024
- pass: true,
1025
- reason: 'Assertion passed',
1026
- });
1027
- });
1028
- it('should fail when the is-sql assertion fails given MySQL Database syntax', async () => {
1029
- const output = `SELECT first_name, last_name FROM employees WHERE first_name ILIKE 'john%'`;
1030
- const result = await (0, assertions_1.runAssertion)({
1031
- prompt: 'Some prompt',
1032
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1033
- assertion: isSqlAssertionWithDatabase,
1034
- test: {},
1035
- providerResponse: { output },
1036
- });
1037
- expect(result).toMatchObject({
1038
- pass: false,
1039
- reason: 'SQL statement does not conform to the provided MySQL database syntax.',
1040
- });
1041
- });
1042
- it('should pass when the is-sql assertion passes given MySQL Database syntax and allowedTables', async () => {
1043
- const output = 'SELECT * FROM departments WHERE department_id = 1';
1044
- const result = await (0, assertions_1.runAssertion)({
1045
- prompt: 'Some prompt',
1046
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1047
- assertion: isSqlAssertionWithDatabaseAndWhiteTableList,
1048
- test: {},
1049
- providerResponse: { output },
1050
- });
1051
- expect(result).toMatchObject({
1052
- pass: true,
1053
- reason: 'Assertion passed',
1054
- });
1055
- });
1056
- it('should fail when the is-sql assertion fails given MySQL Database syntax and allowedTables', async () => {
1057
- const output = 'UPDATE employees SET department_id = 2 WHERE employee_id = 1';
1058
- const result = await (0, assertions_1.runAssertion)({
1059
- prompt: 'Some prompt',
1060
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1061
- assertion: isSqlAssertionWithDatabaseAndWhiteTableList,
1062
- test: {},
1063
- providerResponse: { output },
1064
- });
1065
- expect(result).toMatchObject({
1066
- pass: false,
1067
- reason: `SQL validation failed: authority = 'update::null::employees' is required in table whiteList to execute SQL = 'UPDATE employees SET department_id = 2 WHERE employee_id = 1'.`,
1068
- });
1069
- });
1070
- it('should pass when the is-sql assertion passes given MySQL Database syntax and allowedColumns', async () => {
1071
- const output = 'SELECT name FROM t';
1072
- const result = await (0, assertions_1.runAssertion)({
1073
- prompt: 'Some prompt',
1074
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1075
- assertion: isSqlAssertionWithDatabaseAndWhiteColumnList,
1076
- test: {},
1077
- providerResponse: { output },
1078
- });
1079
- expect(result).toMatchObject({
1080
- pass: true,
1081
- reason: 'Assertion passed',
1082
- });
1083
- });
1084
- it('should fail when the is-sql assertion fails given MySQL Database syntax and allowedColumns', async () => {
1085
- const output = 'SELECT age FROM a WHERE id = 1';
1086
- const result = await (0, assertions_1.runAssertion)({
1087
- prompt: 'Some prompt',
1088
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1089
- assertion: isSqlAssertionWithDatabaseAndWhiteColumnList,
1090
- test: {},
1091
- providerResponse: { output },
1092
- });
1093
- expect(result).toMatchObject({
1094
- pass: false,
1095
- reason: `SQL validation failed: authority = 'select::null::age' is required in column whiteList to execute SQL = 'SELECT age FROM a WHERE id = 1'.`,
935
+ describe('SQL assertions', () => {
936
+ it('should pass when the is-sql assertion passes', async () => {
937
+ const output = 'SELECT id, name FROM users';
938
+ const result = await (0, assertions_1.runAssertion)({
939
+ prompt: 'Some prompt',
940
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
941
+ assertion: isSqlAssertion,
942
+ test: {},
943
+ providerResponse: { output },
944
+ });
945
+ expect(result).toMatchObject({
946
+ pass: true,
947
+ reason: 'Assertion passed',
948
+ });
1096
949
  });
1097
- });
1098
- it('should pass when the is-sql assertion passes given MySQL Database syntax, allowedTables, and allowedColumns', async () => {
1099
- const output = 'SELECT name FROM departments';
1100
- const result = await (0, assertions_1.runAssertion)({
1101
- prompt: 'Some prompt',
1102
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1103
- assertion: isSqlAssertionWithDatabaseAndBothList,
1104
- test: {},
1105
- providerResponse: { output },
950
+ it('should fail when the is-sql assertion fails', async () => {
951
+ const output = 'SELECT * FROM orders ORDERY BY order_date';
952
+ const result = await (0, assertions_1.runAssertion)({
953
+ prompt: 'Some prompt',
954
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
955
+ assertion: isSqlAssertion,
956
+ test: {},
957
+ providerResponse: { output },
958
+ });
959
+ expect(result).toMatchObject({
960
+ pass: false,
961
+ reason: 'SQL statement does not conform to the provided MySQL database syntax.',
962
+ });
1106
963
  });
1107
- expect(result).toMatchObject({
1108
- pass: true,
1109
- reason: 'Assertion passed',
964
+ it('should pass when the not-is-sql assertion passes', async () => {
965
+ const output = 'SELECT * FROM orders ORDERY BY order_date';
966
+ const result = await (0, assertions_1.runAssertion)({
967
+ prompt: 'Some prompt',
968
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
969
+ assertion: notIsSqlAssertion,
970
+ test: {},
971
+ providerResponse: { output },
972
+ });
973
+ expect(result).toMatchObject({
974
+ pass: true,
975
+ reason: 'Assertion passed',
976
+ });
1110
977
  });
1111
- });
1112
- it('should fail when the is-sql assertion fails given MySQL Database syntax, allowedTables, and allowedColumns', async () => {
1113
- const output = `INSERT INTO departments (name) VALUES ('HR')`;
1114
- const result = await (0, assertions_1.runAssertion)({
1115
- prompt: 'Some prompt',
1116
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1117
- assertion: isSqlAssertionWithDatabaseAndBothList,
1118
- test: {},
1119
- providerResponse: { output },
978
+ it('should fail when the not-is-sql assertion fails', async () => {
979
+ const output = 'SELECT id, name FROM users';
980
+ const result = await (0, assertions_1.runAssertion)({
981
+ prompt: 'Some prompt',
982
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
983
+ assertion: notIsSqlAssertion,
984
+ test: {},
985
+ providerResponse: { output },
986
+ });
987
+ expect(result).toMatchObject({
988
+ pass: false,
989
+ reason: 'The output SQL statement is valid',
990
+ });
1120
991
  });
1121
- expect(result).toMatchObject({
1122
- pass: false,
1123
- reason: `SQL validation failed: authority = 'insert::departments::name' is required in column whiteList to execute SQL = 'INSERT INTO departments (name) VALUES ('HR')'.`,
992
+ it('should pass when the is-sql assertion passes given MySQL Database syntax', async () => {
993
+ const output = 'SELECT id, name FROM users';
994
+ const result = await (0, assertions_1.runAssertion)({
995
+ prompt: 'Some prompt',
996
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
997
+ assertion: isSqlAssertionWithDatabase,
998
+ test: {},
999
+ providerResponse: { output },
1000
+ });
1001
+ expect(result).toMatchObject({
1002
+ pass: true,
1003
+ reason: 'Assertion passed',
1004
+ });
1124
1005
  });
1125
- });
1126
- it('should fail when the is-sql assertion fails due to missing table authority for MySQL Database syntax', async () => {
1127
- const output = 'UPDATE a SET id = 1';
1128
- const result = await (0, assertions_1.runAssertion)({
1129
- prompt: 'Some prompt',
1130
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1131
- assertion: isSqlAssertionWithDatabaseAndBothList,
1132
- test: {},
1133
- providerResponse: { output },
1006
+ it('should fail when the is-sql assertion fails given MySQL Database syntax', async () => {
1007
+ const output = `SELECT first_name, last_name FROM employees WHERE first_name ILIKE 'john%'`;
1008
+ const result = await (0, assertions_1.runAssertion)({
1009
+ prompt: 'Some prompt',
1010
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1011
+ assertion: isSqlAssertionWithDatabase,
1012
+ test: {},
1013
+ providerResponse: { output },
1014
+ });
1015
+ expect(result).toMatchObject({
1016
+ pass: false,
1017
+ reason: 'SQL statement does not conform to the provided MySQL database syntax.',
1018
+ });
1134
1019
  });
1135
- expect(result).toMatchObject({
1136
- pass: false,
1137
- reason: `SQL validation failed: authority = 'update::null::a' is required in table whiteList to execute SQL = 'UPDATE a SET id = 1'.`,
1020
+ it('should pass when the is-sql assertion passes given MySQL Database syntax and allowedTables', async () => {
1021
+ const output = 'SELECT * FROM departments WHERE department_id = 1';
1022
+ const result = await (0, assertions_1.runAssertion)({
1023
+ prompt: 'Some prompt',
1024
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1025
+ assertion: isSqlAssertionWithDatabaseAndWhiteTableList,
1026
+ test: {},
1027
+ providerResponse: { output },
1028
+ });
1029
+ expect(result).toMatchObject({
1030
+ pass: true,
1031
+ reason: 'Assertion passed',
1032
+ });
1138
1033
  });
1139
- });
1140
- it('should fail when the is-sql assertion fails due to missing authorities for DELETE statement in MySQL Database syntax', async () => {
1141
- const output = `DELETE FROM employees;`;
1142
- const result = await (0, assertions_1.runAssertion)({
1143
- prompt: 'Some prompt',
1144
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1145
- assertion: isSqlAssertionWithDatabaseAndBothList,
1146
- test: {},
1147
- providerResponse: { output },
1034
+ it('should fail when the is-sql assertion fails given MySQL Database syntax and allowedTables', async () => {
1035
+ const output = 'UPDATE employees SET department_id = 2 WHERE employee_id = 1';
1036
+ const result = await (0, assertions_1.runAssertion)({
1037
+ prompt: 'Some prompt',
1038
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1039
+ assertion: isSqlAssertionWithDatabaseAndWhiteTableList,
1040
+ test: {},
1041
+ providerResponse: { output },
1042
+ });
1043
+ expect(result).toMatchObject({
1044
+ pass: false,
1045
+ reason: `SQL validation failed: authority = 'update::null::employees' is required in table whiteList to execute SQL = 'UPDATE employees SET department_id = 2 WHERE employee_id = 1'.`,
1046
+ });
1148
1047
  });
1149
- expect(result).toMatchObject({
1150
- pass: false,
1151
- reason: `SQL validation failed: authority = 'delete::null::employees' is required in table whiteList to execute SQL = 'DELETE FROM employees;'. SQL validation failed: authority = 'delete::employees::(.*)' is required in column whiteList to execute SQL = 'DELETE FROM employees;'.`,
1048
+ it('should pass when the is-sql assertion passes given MySQL Database syntax and allowedColumns', async () => {
1049
+ const output = 'SELECT name FROM t';
1050
+ const result = await (0, assertions_1.runAssertion)({
1051
+ prompt: 'Some prompt',
1052
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1053
+ assertion: isSqlAssertionWithDatabaseAndWhiteColumnList,
1054
+ test: {},
1055
+ providerResponse: { output },
1056
+ });
1057
+ expect(result).toMatchObject({
1058
+ pass: true,
1059
+ reason: 'Assertion passed',
1060
+ });
1152
1061
  });
1153
- });
1154
- it('should pass when the contains-sql assertion passes', async () => {
1155
- const output = 'wassup\n```\nSELECT id, name FROM users\n```\nyolo';
1156
- const result = await (0, assertions_1.runAssertion)({
1157
- prompt: 'Some prompt',
1158
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1159
- assertion: {
1160
- type: 'contains-sql',
1161
- },
1162
- test: {},
1163
- providerResponse: { output },
1062
+ it('should fail when the is-sql assertion fails given MySQL Database syntax and allowedColumns', async () => {
1063
+ const output = 'SELECT age FROM a WHERE id = 1';
1064
+ const result = await (0, assertions_1.runAssertion)({
1065
+ prompt: 'Some prompt',
1066
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1067
+ assertion: isSqlAssertionWithDatabaseAndWhiteColumnList,
1068
+ test: {},
1069
+ providerResponse: { output },
1070
+ });
1071
+ expect(result).toMatchObject({
1072
+ pass: false,
1073
+ reason: `SQL validation failed: authority = 'select::null::age' is required in column whiteList to execute SQL = 'SELECT age FROM a WHERE id = 1'.`,
1074
+ });
1164
1075
  });
1165
- expect(result).toMatchObject({
1166
- pass: true,
1167
- reason: 'Assertion passed',
1076
+ it('should pass when the is-sql assertion passes given MySQL Database syntax, allowedTables, and allowedColumns', async () => {
1077
+ const output = 'SELECT name FROM departments';
1078
+ const result = await (0, assertions_1.runAssertion)({
1079
+ prompt: 'Some prompt',
1080
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1081
+ assertion: isSqlAssertionWithDatabaseAndBothList,
1082
+ test: {},
1083
+ providerResponse: { output },
1084
+ });
1085
+ expect(result).toMatchObject({
1086
+ pass: true,
1087
+ reason: 'Assertion passed',
1088
+ });
1168
1089
  });
1169
- });
1170
- it('should pass when the contains-sql assertion sees `sql` in code block', async () => {
1171
- const output = 'wassup\n```sql\nSELECT id, name FROM users\n```\nyolo';
1172
- const result = await (0, assertions_1.runAssertion)({
1173
- prompt: 'Some prompt',
1174
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1175
- assertion: {
1176
- type: 'contains-sql',
1177
- },
1178
- test: {},
1179
- providerResponse: { output },
1090
+ it('should fail when the is-sql assertion fails given MySQL Database syntax, allowedTables, and allowedColumns', async () => {
1091
+ const output = `INSERT INTO departments (name) VALUES ('HR')`;
1092
+ const result = await (0, assertions_1.runAssertion)({
1093
+ prompt: 'Some prompt',
1094
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1095
+ assertion: isSqlAssertionWithDatabaseAndBothList,
1096
+ test: {},
1097
+ providerResponse: { output },
1098
+ });
1099
+ expect(result).toMatchObject({
1100
+ pass: false,
1101
+ reason: `SQL validation failed: authority = 'insert::departments::name' is required in column whiteList to execute SQL = 'INSERT INTO departments (name) VALUES ('HR')'.`,
1102
+ });
1180
1103
  });
1181
- expect(result).toMatchObject({
1182
- pass: true,
1183
- reason: 'Assertion passed',
1104
+ it('should fail when the is-sql assertion fails due to missing table authority for MySQL Database syntax', async () => {
1105
+ const output = 'UPDATE a SET id = 1';
1106
+ const result = await (0, assertions_1.runAssertion)({
1107
+ prompt: 'Some prompt',
1108
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1109
+ assertion: isSqlAssertionWithDatabaseAndBothList,
1110
+ test: {},
1111
+ providerResponse: { output },
1112
+ });
1113
+ expect(result).toMatchObject({
1114
+ pass: false,
1115
+ reason: `SQL validation failed: authority = 'update::null::a' is required in table whiteList to execute SQL = 'UPDATE a SET id = 1'.`,
1116
+ });
1184
1117
  });
1185
- });
1186
- it('should pass when the contains-sql assertion sees sql without code block', async () => {
1187
- const output = 'SELECT id, name FROM users';
1188
- const result = await (0, assertions_1.runAssertion)({
1189
- prompt: 'Some prompt',
1190
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1191
- assertion: {
1192
- type: 'contains-sql',
1193
- },
1194
- test: {},
1195
- providerResponse: { output },
1118
+ it('should fail when the is-sql assertion fails due to missing authorities for DELETE statement in MySQL Database syntax', async () => {
1119
+ const output = `DELETE FROM employees;`;
1120
+ const result = await (0, assertions_1.runAssertion)({
1121
+ prompt: 'Some prompt',
1122
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1123
+ assertion: isSqlAssertionWithDatabaseAndBothList,
1124
+ test: {},
1125
+ providerResponse: { output },
1126
+ });
1127
+ expect(result).toMatchObject({
1128
+ pass: false,
1129
+ reason: `SQL validation failed: authority = 'delete::null::employees' is required in table whiteList to execute SQL = 'DELETE FROM employees;'. SQL validation failed: authority = 'delete::employees::(.*)' is required in column whiteList to execute SQL = 'DELETE FROM employees;'.`,
1130
+ });
1196
1131
  });
1197
- expect(result).toMatchObject({
1198
- pass: true,
1199
- reason: 'Assertion passed',
1132
+ it('should pass when the contains-sql assertion passes', async () => {
1133
+ const output = 'wassup\n```\nSELECT id, name FROM users\n```\nyolo';
1134
+ const result = await (0, assertions_1.runAssertion)({
1135
+ prompt: 'Some prompt',
1136
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1137
+ assertion: {
1138
+ type: 'contains-sql',
1139
+ },
1140
+ test: {},
1141
+ providerResponse: { output },
1142
+ });
1143
+ expect(result).toMatchObject({
1144
+ pass: true,
1145
+ reason: 'Assertion passed',
1146
+ });
1200
1147
  });
1201
- });
1202
- it('should fail when the contains-sql does not contain code block', async () => {
1203
- const output = 'nothin';
1204
- const result = await (0, assertions_1.runAssertion)({
1205
- prompt: 'Some prompt',
1206
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1207
- assertion: {
1208
- type: 'contains-sql',
1209
- },
1210
- test: {},
1211
- providerResponse: { output },
1148
+ it('should pass when the contains-sql assertion sees `sql` in code block', async () => {
1149
+ const output = 'wassup\n```sql\nSELECT id, name FROM users\n```\nyolo';
1150
+ const result = await (0, assertions_1.runAssertion)({
1151
+ prompt: 'Some prompt',
1152
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1153
+ assertion: {
1154
+ type: 'contains-sql',
1155
+ },
1156
+ test: {},
1157
+ providerResponse: { output },
1158
+ });
1159
+ expect(result).toMatchObject({
1160
+ pass: true,
1161
+ reason: 'Assertion passed',
1162
+ });
1212
1163
  });
1213
- expect(result).toMatchObject({
1214
- pass: false,
1164
+ it('should pass when the contains-sql assertion sees sql without code block', async () => {
1165
+ const output = 'SELECT id, name FROM users';
1166
+ const result = await (0, assertions_1.runAssertion)({
1167
+ prompt: 'Some prompt',
1168
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1169
+ assertion: {
1170
+ type: 'contains-sql',
1171
+ },
1172
+ test: {},
1173
+ providerResponse: { output },
1174
+ });
1175
+ expect(result).toMatchObject({
1176
+ pass: true,
1177
+ reason: 'Assertion passed',
1178
+ });
1215
1179
  });
1216
- });
1217
- it('should fail when the contains-sql does not contain sql in code block', async () => {
1218
- const output = '```python\nprint("Hello, World!")\n```';
1219
- const result = await (0, assertions_1.runAssertion)({
1220
- prompt: 'Some prompt',
1221
- provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1222
- assertion: {
1223
- type: 'contains-sql',
1224
- },
1225
- test: {},
1226
- providerResponse: { output },
1180
+ it('should fail when the contains-sql does not contain code block', async () => {
1181
+ const output = 'nothin';
1182
+ const result = await (0, assertions_1.runAssertion)({
1183
+ prompt: 'Some prompt',
1184
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1185
+ assertion: {
1186
+ type: 'contains-sql',
1187
+ },
1188
+ test: {},
1189
+ providerResponse: { output },
1190
+ });
1191
+ expect(result).toMatchObject({
1192
+ pass: false,
1193
+ });
1227
1194
  });
1228
- expect(result).toMatchObject({
1229
- pass: false,
1195
+ it('should fail when the contains-sql does not contain sql in code block', async () => {
1196
+ const output = '```python\nprint("Hello, World!")\n```';
1197
+ const result = await (0, assertions_1.runAssertion)({
1198
+ prompt: 'Some prompt',
1199
+ provider: new openai_1.OpenAiChatCompletionProvider('gpt-4o-mini'),
1200
+ assertion: {
1201
+ type: 'contains-sql',
1202
+ },
1203
+ test: {},
1204
+ providerResponse: { output },
1205
+ });
1206
+ expect(result).toMatchObject({
1207
+ pass: false,
1208
+ });
1230
1209
  });
1231
1210
  });
1232
1211
  it('should pass when the contains-json assertion passes', async () => {
@@ -3468,37 +3447,37 @@ describe('runAssertion', () => {
3468
3447
  });
3469
3448
  describe('validateXml', () => {
3470
3449
  it('should validate a simple valid XML string', () => {
3471
- expect((0, assertions_1.validateXml)('<root><child>Content</child></root>')).toEqual({
3450
+ expect((0, xml_1.validateXml)('<root><child>Content</child></root>')).toEqual({
3472
3451
  isValid: true,
3473
3452
  reason: 'XML is valid and contains all required elements',
3474
3453
  });
3475
3454
  });
3476
3455
  it('should invalidate a malformed XML string', () => {
3477
- expect((0, assertions_1.validateXml)('<root><child>Content</child></root')).toEqual({
3456
+ expect((0, xml_1.validateXml)('<root><child>Content</child></root')).toEqual({
3478
3457
  isValid: false,
3479
3458
  reason: expect.stringContaining('XML parsing failed'),
3480
3459
  });
3481
3460
  });
3482
3461
  it('should validate XML with attributes', () => {
3483
- expect((0, assertions_1.validateXml)('<root><child id="1">Content</child></root>')).toEqual({
3462
+ expect((0, xml_1.validateXml)('<root><child id="1">Content</child></root>')).toEqual({
3484
3463
  isValid: true,
3485
3464
  reason: 'XML is valid and contains all required elements',
3486
3465
  });
3487
3466
  });
3488
3467
  it('should validate XML with namespaces', () => {
3489
- expect((0, assertions_1.validateXml)('<root xmlns:ns="http://example.com"><ns:child>Content</ns:child></root>')).toEqual({
3468
+ expect((0, xml_1.validateXml)('<root xmlns:ns="http://example.com"><ns:child>Content</ns:child></root>')).toEqual({
3490
3469
  isValid: true,
3491
3470
  reason: 'XML is valid and contains all required elements',
3492
3471
  });
3493
3472
  });
3494
3473
  it('should validate when all required elements are present', () => {
3495
- expect((0, assertions_1.validateXml)('<analysis><classification>T-shirt</classification><color>Red</color></analysis>', ['analysis.classification', 'analysis.color'])).toEqual({
3474
+ expect((0, xml_1.validateXml)('<analysis><classification>T-shirt</classification><color>Red</color></analysis>', ['analysis.classification', 'analysis.color'])).toEqual({
3496
3475
  isValid: true,
3497
3476
  reason: 'XML is valid and contains all required elements',
3498
3477
  });
3499
3478
  });
3500
3479
  it('should invalidate when a required element is missing', () => {
3501
- expect((0, assertions_1.validateXml)('<analysis><classification>T-shirt</classification></analysis>', [
3480
+ expect((0, xml_1.validateXml)('<analysis><classification>T-shirt</classification></analysis>', [
3502
3481
  'analysis.classification',
3503
3482
  'analysis.color',
3504
3483
  ])).toEqual({
@@ -3507,7 +3486,7 @@ describe('validateXml', () => {
3507
3486
  });
3508
3487
  });
3509
3488
  it('should validate nested elements correctly', () => {
3510
- expect((0, assertions_1.validateXml)('<root><parent><child><grandchild>Content</grandchild></child></parent></root>', [
3489
+ expect((0, xml_1.validateXml)('<root><parent><child><grandchild>Content</grandchild></child></parent></root>', [
3511
3490
  'root.parent.child.grandchild',
3512
3491
  ])).toEqual({
3513
3492
  isValid: true,
@@ -3515,7 +3494,7 @@ describe('validateXml', () => {
3515
3494
  });
3516
3495
  });
3517
3496
  it('should invalidate when a nested required element is missing', () => {
3518
- expect((0, assertions_1.validateXml)('<root><parent><child></child></parent></root>', [
3497
+ expect((0, xml_1.validateXml)('<root><parent><child></child></parent></root>', [
3519
3498
  'root.parent.child.grandchild',
3520
3499
  ])).toEqual({
3521
3500
  isValid: false,
@@ -3523,7 +3502,7 @@ describe('validateXml', () => {
3523
3502
  });
3524
3503
  });
3525
3504
  it('should handle empty elements correctly', () => {
3526
- expect((0, assertions_1.validateXml)('<root><emptyChild></emptyChild><nonEmptyChild>Content</nonEmptyChild></root>', [
3505
+ expect((0, xml_1.validateXml)('<root><emptyChild></emptyChild><nonEmptyChild>Content</nonEmptyChild></root>', [
3527
3506
  'root.emptyChild',
3528
3507
  'root.nonEmptyChild',
3529
3508
  ])).toEqual({
@@ -3532,13 +3511,13 @@ describe('validateXml', () => {
3532
3511
  });
3533
3512
  });
3534
3513
  it('should validate XML with multiple siblings', () => {
3535
- expect((0, assertions_1.validateXml)('<root><child>Content1</child><child>Content2</child></root>', ['root.child'])).toEqual({
3514
+ expect((0, xml_1.validateXml)('<root><child>Content1</child><child>Content2</child></root>', ['root.child'])).toEqual({
3536
3515
  isValid: true,
3537
3516
  reason: 'XML is valid and contains all required elements',
3538
3517
  });
3539
3518
  });
3540
3519
  it('should handle XML with CDATA sections', () => {
3541
- expect((0, assertions_1.validateXml)('<root><child><![CDATA[<p>This is CDATA content</p>]]></child></root>', [
3520
+ expect((0, xml_1.validateXml)('<root><child><![CDATA[<p>This is CDATA content</p>]]></child></root>', [
3542
3521
  'root.child',
3543
3522
  ])).toEqual({
3544
3523
  isValid: true,
@@ -3547,13 +3526,13 @@ describe('validateXml', () => {
3547
3526
  });
3548
3527
  it('should validate XML with processing instructions', () => {
3549
3528
  const xml = '<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="style.xsl"?><root><child>Content</child></root>';
3550
- expect((0, assertions_1.validateXml)(xml, ['root.child'])).toEqual({
3529
+ expect((0, xml_1.validateXml)(xml, ['root.child'])).toEqual({
3551
3530
  isValid: true,
3552
3531
  reason: 'XML is valid and contains all required elements',
3553
3532
  });
3554
3533
  });
3555
3534
  it('should handle XML with comments', () => {
3556
- expect((0, assertions_1.validateXml)('<root><!-- This is a comment --><child>Content</child></root>', ['root.child'])).toEqual({
3535
+ expect((0, xml_1.validateXml)('<root><!-- This is a comment --><child>Content</child></root>', ['root.child'])).toEqual({
3557
3536
  isValid: true,
3558
3537
  reason: 'XML is valid and contains all required elements',
3559
3538
  });
@@ -3569,7 +3548,7 @@ describe('validateXml', () => {
3569
3548
  <reasoning>The image clearly shows a short-sleeved garment with a round neckline, which is characteristic of a T-shirt. The large circular graphic on the front is distinctive and appears to be a stylized smiley face or emoji design, which is popular in contemporary casual fashion. The stark contrast between the white fabric and black print is very clear, leaving little room for misinterpretation. The style is unmistakably modern and aligned with current trends in graphic tees. My confidence is high (9) because all elements of the image are clear and consistent with a typical graphic T-shirt design.</reasoning>
3570
3549
  </analysis>
3571
3550
  `;
3572
- expect((0, assertions_1.validateXml)(xml, [
3551
+ expect((0, xml_1.validateXml)(xml, [
3573
3552
  'analysis.classification',
3574
3553
  'analysis.color',
3575
3554
  'analysis.features',
@@ -3585,31 +3564,31 @@ describe('validateXml', () => {
3585
3564
  describe('containsXml', () => {
3586
3565
  it('should return true when valid XML is present', () => {
3587
3566
  const input = 'Some text <root><child>Content</child></root> more text';
3588
- const result = (0, assertions_1.containsXml)(input);
3567
+ const result = (0, xml_1.containsXml)(input);
3589
3568
  expect(result.isValid).toBe(true);
3590
3569
  });
3591
3570
  it('should return false when no XML is present', () => {
3592
3571
  const input = 'This is just plain text';
3593
- expect((0, assertions_1.containsXml)(input)).toEqual({
3572
+ expect((0, xml_1.containsXml)(input)).toEqual({
3594
3573
  isValid: false,
3595
3574
  reason: 'No XML content found in the output',
3596
3575
  });
3597
3576
  });
3598
3577
  it('should validate required elements', () => {
3599
3578
  const input = 'Text <root><child>Content</child></root> more';
3600
- const result = (0, assertions_1.containsXml)(input, ['root.child']);
3579
+ const result = (0, xml_1.containsXml)(input, ['root.child']);
3601
3580
  expect(result.isValid).toBe(true);
3602
3581
  });
3603
3582
  it('should return false when required elements are missing', () => {
3604
3583
  const input = 'Text <root><child>Content</child></root> more';
3605
- expect((0, assertions_1.containsXml)(input, ['root.missing'])).toEqual({
3584
+ expect((0, xml_1.containsXml)(input, ['root.missing'])).toEqual({
3606
3585
  isValid: false,
3607
3586
  reason: 'No valid XML content found matching the requirements',
3608
3587
  });
3609
3588
  });
3610
3589
  it('should handle multiple XML fragments', () => {
3611
3590
  const input = '<root1>Content</root1> text <root2><child>More</child></root2>';
3612
- const result = (0, assertions_1.containsXml)(input, ['root2.child']);
3591
+ const result = (0, xml_1.containsXml)(input, ['root2.child']);
3613
3592
  expect(result.isValid).toBe(true);
3614
3593
  });
3615
3594
  });