@cdot65/prisma-airs-cli 1.0.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 (234) hide show
  1. package/README.md +42 -0
  2. package/dist/airs/management.d.ts +58 -0
  3. package/dist/airs/management.d.ts.map +1 -0
  4. package/dist/airs/management.js +287 -0
  5. package/dist/airs/management.js.map +1 -0
  6. package/dist/airs/modelsecurity.d.ts +74 -0
  7. package/dist/airs/modelsecurity.d.ts.map +1 -0
  8. package/dist/airs/modelsecurity.js +337 -0
  9. package/dist/airs/modelsecurity.js.map +1 -0
  10. package/dist/airs/promptsets.d.ts +50 -0
  11. package/dist/airs/promptsets.d.ts.map +1 -0
  12. package/dist/airs/promptsets.js +133 -0
  13. package/dist/airs/promptsets.js.map +1 -0
  14. package/dist/airs/redteam.d.ts +45 -0
  15. package/dist/airs/redteam.d.ts.map +1 -0
  16. package/dist/airs/redteam.js +219 -0
  17. package/dist/airs/redteam.js.map +1 -0
  18. package/dist/airs/runtime.d.ts +27 -0
  19. package/dist/airs/runtime.d.ts.map +1 -0
  20. package/dist/airs/runtime.js +158 -0
  21. package/dist/airs/runtime.js.map +1 -0
  22. package/dist/airs/scanner.d.ts +22 -0
  23. package/dist/airs/scanner.d.ts.map +1 -0
  24. package/dist/airs/scanner.js +62 -0
  25. package/dist/airs/scanner.js.map +1 -0
  26. package/dist/airs/types.d.ts +683 -0
  27. package/dist/airs/types.d.ts.map +1 -0
  28. package/dist/airs/types.js +6 -0
  29. package/dist/airs/types.js.map +1 -0
  30. package/dist/audit/evaluator.d.ts +17 -0
  31. package/dist/audit/evaluator.d.ts.map +1 -0
  32. package/dist/audit/evaluator.js +82 -0
  33. package/dist/audit/evaluator.js.map +1 -0
  34. package/dist/audit/report.d.ts +38 -0
  35. package/dist/audit/report.d.ts.map +1 -0
  36. package/dist/audit/report.js +141 -0
  37. package/dist/audit/report.js.map +1 -0
  38. package/dist/audit/runner.d.ts +18 -0
  39. package/dist/audit/runner.d.ts.map +1 -0
  40. package/dist/audit/runner.js +60 -0
  41. package/dist/audit/runner.js.map +1 -0
  42. package/dist/audit/types.d.ts +53 -0
  43. package/dist/audit/types.d.ts.map +1 -0
  44. package/dist/audit/types.js +5 -0
  45. package/dist/audit/types.js.map +1 -0
  46. package/dist/cli/bulk-scan-state.d.ts +15 -0
  47. package/dist/cli/bulk-scan-state.d.ts.map +1 -0
  48. package/dist/cli/bulk-scan-state.js +20 -0
  49. package/dist/cli/bulk-scan-state.js.map +1 -0
  50. package/dist/cli/commands/audit.d.ts +4 -0
  51. package/dist/cli/commands/audit.d.ts.map +1 -0
  52. package/dist/cli/commands/audit.js +113 -0
  53. package/dist/cli/commands/audit.js.map +1 -0
  54. package/dist/cli/commands/generate.d.ts +4 -0
  55. package/dist/cli/commands/generate.d.ts.map +1 -0
  56. package/dist/cli/commands/generate.js +231 -0
  57. package/dist/cli/commands/generate.js.map +1 -0
  58. package/dist/cli/commands/list.d.ts +4 -0
  59. package/dist/cli/commands/list.d.ts.map +1 -0
  60. package/dist/cli/commands/list.js +23 -0
  61. package/dist/cli/commands/list.js.map +1 -0
  62. package/dist/cli/commands/modelsecurity.d.ts +4 -0
  63. package/dist/cli/commands/modelsecurity.d.ts.map +1 -0
  64. package/dist/cli/commands/modelsecurity.js +499 -0
  65. package/dist/cli/commands/modelsecurity.js.map +1 -0
  66. package/dist/cli/commands/redteam.d.ts +4 -0
  67. package/dist/cli/commands/redteam.d.ts.map +1 -0
  68. package/dist/cli/commands/redteam.js +630 -0
  69. package/dist/cli/commands/redteam.js.map +1 -0
  70. package/dist/cli/commands/report.d.ts +4 -0
  71. package/dist/cli/commands/report.d.ts.map +1 -0
  72. package/dist/cli/commands/report.js +116 -0
  73. package/dist/cli/commands/report.js.map +1 -0
  74. package/dist/cli/commands/resume.d.ts +4 -0
  75. package/dist/cli/commands/resume.d.ts.map +1 -0
  76. package/dist/cli/commands/resume.js +138 -0
  77. package/dist/cli/commands/resume.js.map +1 -0
  78. package/dist/cli/commands/runtime.d.ts +3 -0
  79. package/dist/cli/commands/runtime.d.ts.map +1 -0
  80. package/dist/cli/commands/runtime.js +582 -0
  81. package/dist/cli/commands/runtime.js.map +1 -0
  82. package/dist/cli/index.d.ts +3 -0
  83. package/dist/cli/index.d.ts.map +1 -0
  84. package/dist/cli/index.js +46 -0
  85. package/dist/cli/index.js.map +1 -0
  86. package/dist/cli/parse-input.d.ts +9 -0
  87. package/dist/cli/parse-input.d.ts.map +1 -0
  88. package/dist/cli/parse-input.js +109 -0
  89. package/dist/cli/parse-input.js.map +1 -0
  90. package/dist/cli/prompts.d.ts +9 -0
  91. package/dist/cli/prompts.d.ts.map +1 -0
  92. package/dist/cli/prompts.js +90 -0
  93. package/dist/cli/prompts.js.map +1 -0
  94. package/dist/cli/renderer/audit.d.ts +8 -0
  95. package/dist/cli/renderer/audit.d.ts.map +1 -0
  96. package/dist/cli/renderer/audit.js +44 -0
  97. package/dist/cli/renderer/audit.js.map +1 -0
  98. package/dist/cli/renderer/common.d.ts +3 -0
  99. package/dist/cli/renderer/common.d.ts.map +1 -0
  100. package/dist/cli/renderer/common.js +6 -0
  101. package/dist/cli/renderer/common.js.map +1 -0
  102. package/dist/cli/renderer/generate.d.ts +29 -0
  103. package/dist/cli/renderer/generate.d.ts.map +1 -0
  104. package/dist/cli/renderer/generate.js +132 -0
  105. package/dist/cli/renderer/generate.js.map +1 -0
  106. package/dist/cli/renderer/index.d.ts +7 -0
  107. package/dist/cli/renderer/index.d.ts.map +1 -0
  108. package/dist/cli/renderer/index.js +7 -0
  109. package/dist/cli/renderer/index.js.map +1 -0
  110. package/dist/cli/renderer/modelsecurity.d.ts +34 -0
  111. package/dist/cli/renderer/modelsecurity.d.ts.map +1 -0
  112. package/dist/cli/renderer/modelsecurity.js +285 -0
  113. package/dist/cli/renderer/modelsecurity.js.map +1 -0
  114. package/dist/cli/renderer/redteam.d.ts +152 -0
  115. package/dist/cli/renderer/redteam.d.ts.map +1 -0
  116. package/dist/cli/renderer/redteam.js +294 -0
  117. package/dist/cli/renderer/redteam.js.map +1 -0
  118. package/dist/cli/renderer/runtime.d.ts +87 -0
  119. package/dist/cli/renderer/runtime.d.ts.map +1 -0
  120. package/dist/cli/renderer/runtime.js +230 -0
  121. package/dist/cli/renderer/runtime.js.map +1 -0
  122. package/dist/config/loader.d.ts +3 -0
  123. package/dist/config/loader.d.ts.map +1 -0
  124. package/dist/config/loader.js +65 -0
  125. package/dist/config/loader.js.map +1 -0
  126. package/dist/config/schema.d.ts +78 -0
  127. package/dist/config/schema.d.ts.map +1 -0
  128. package/dist/config/schema.js +44 -0
  129. package/dist/config/schema.js.map +1 -0
  130. package/dist/core/constraints.d.ts +18 -0
  131. package/dist/core/constraints.d.ts.map +1 -0
  132. package/dist/core/constraints.js +75 -0
  133. package/dist/core/constraints.js.map +1 -0
  134. package/dist/core/loop.d.ts +54 -0
  135. package/dist/core/loop.d.ts.map +1 -0
  136. package/dist/core/loop.js +462 -0
  137. package/dist/core/loop.js.map +1 -0
  138. package/dist/core/metrics.d.ts +13 -0
  139. package/dist/core/metrics.d.ts.map +1 -0
  140. package/dist/core/metrics.js +73 -0
  141. package/dist/core/metrics.js.map +1 -0
  142. package/dist/core/types.d.ts +175 -0
  143. package/dist/core/types.d.ts.map +1 -0
  144. package/dist/core/types.js +5 -0
  145. package/dist/core/types.js.map +1 -0
  146. package/dist/index.d.ts +35 -0
  147. package/dist/index.d.ts.map +1 -0
  148. package/dist/index.js +49 -0
  149. package/dist/index.js.map +1 -0
  150. package/dist/llm/prompts/analyze-results.d.ts +3 -0
  151. package/dist/llm/prompts/analyze-results.d.ts.map +1 -0
  152. package/dist/llm/prompts/analyze-results.js +52 -0
  153. package/dist/llm/prompts/analyze-results.js.map +1 -0
  154. package/dist/llm/prompts/generate-companion.d.ts +3 -0
  155. package/dist/llm/prompts/generate-companion.d.ts.map +1 -0
  156. package/dist/llm/prompts/generate-companion.js +42 -0
  157. package/dist/llm/prompts/generate-companion.js.map +1 -0
  158. package/dist/llm/prompts/generate-tests.d.ts +3 -0
  159. package/dist/llm/prompts/generate-tests.d.ts.map +1 -0
  160. package/dist/llm/prompts/generate-tests.js +46 -0
  161. package/dist/llm/prompts/generate-tests.js.map +1 -0
  162. package/dist/llm/prompts/generate-topic.d.ts +4 -0
  163. package/dist/llm/prompts/generate-topic.d.ts.map +1 -0
  164. package/dist/llm/prompts/generate-topic.js +41 -0
  165. package/dist/llm/prompts/generate-topic.js.map +1 -0
  166. package/dist/llm/prompts/improve-topic.d.ts +3 -0
  167. package/dist/llm/prompts/improve-topic.d.ts.map +1 -0
  168. package/dist/llm/prompts/improve-topic.js +77 -0
  169. package/dist/llm/prompts/improve-topic.js.map +1 -0
  170. package/dist/llm/prompts/simplify-topic.d.ts +3 -0
  171. package/dist/llm/prompts/simplify-topic.d.ts.map +1 -0
  172. package/dist/llm/prompts/simplify-topic.js +50 -0
  173. package/dist/llm/prompts/simplify-topic.js.map +1 -0
  174. package/dist/llm/provider.d.ts +21 -0
  175. package/dist/llm/provider.d.ts.map +1 -0
  176. package/dist/llm/provider.js +76 -0
  177. package/dist/llm/provider.js.map +1 -0
  178. package/dist/llm/schemas.d.ts +97 -0
  179. package/dist/llm/schemas.d.ts.map +1 -0
  180. package/dist/llm/schemas.js +24 -0
  181. package/dist/llm/schemas.js.map +1 -0
  182. package/dist/llm/service.d.ts +30 -0
  183. package/dist/llm/service.d.ts.map +1 -0
  184. package/dist/llm/service.js +273 -0
  185. package/dist/llm/service.js.map +1 -0
  186. package/dist/memory/diff.d.ts +4 -0
  187. package/dist/memory/diff.d.ts.map +1 -0
  188. package/dist/memory/diff.js +24 -0
  189. package/dist/memory/diff.js.map +1 -0
  190. package/dist/memory/extractor.d.ts +15 -0
  191. package/dist/memory/extractor.d.ts.map +1 -0
  192. package/dist/memory/extractor.js +133 -0
  193. package/dist/memory/extractor.js.map +1 -0
  194. package/dist/memory/injector.d.ts +22 -0
  195. package/dist/memory/injector.d.ts.map +1 -0
  196. package/dist/memory/injector.js +90 -0
  197. package/dist/memory/injector.js.map +1 -0
  198. package/dist/memory/prompts/extract-learnings.d.ts +3 -0
  199. package/dist/memory/prompts/extract-learnings.d.ts.map +1 -0
  200. package/dist/memory/prompts/extract-learnings.js +40 -0
  201. package/dist/memory/prompts/extract-learnings.js.map +1 -0
  202. package/dist/memory/schemas.d.ts +63 -0
  203. package/dist/memory/schemas.d.ts.map +1 -0
  204. package/dist/memory/schemas.js +13 -0
  205. package/dist/memory/schemas.js.map +1 -0
  206. package/dist/memory/store.d.ts +28 -0
  207. package/dist/memory/store.d.ts.map +1 -0
  208. package/dist/memory/store.js +103 -0
  209. package/dist/memory/store.js.map +1 -0
  210. package/dist/memory/types.d.ts +55 -0
  211. package/dist/memory/types.d.ts.map +1 -0
  212. package/dist/memory/types.js +6 -0
  213. package/dist/memory/types.js.map +1 -0
  214. package/dist/persistence/store.d.ts +21 -0
  215. package/dist/persistence/store.d.ts.map +1 -0
  216. package/dist/persistence/store.js +77 -0
  217. package/dist/persistence/store.js.map +1 -0
  218. package/dist/persistence/types.d.ts +23 -0
  219. package/dist/persistence/types.d.ts.map +1 -0
  220. package/dist/persistence/types.js +2 -0
  221. package/dist/persistence/types.js.map +1 -0
  222. package/dist/report/html.d.ts +6 -0
  223. package/dist/report/html.d.ts.map +1 -0
  224. package/dist/report/html.js +200 -0
  225. package/dist/report/html.js.map +1 -0
  226. package/dist/report/json.d.ts +11 -0
  227. package/dist/report/json.d.ts.map +1 -0
  228. package/dist/report/json.js +74 -0
  229. package/dist/report/json.js.map +1 -0
  230. package/dist/report/types.d.ts +58 -0
  231. package/dist/report/types.d.ts.map +1 -0
  232. package/dist/report/types.js +5 -0
  233. package/dist/report/types.js.map +1 -0
  234. package/package.json +67 -0
@@ -0,0 +1,24 @@
1
+ export function computeIterationDiff(from, to) {
2
+ const fromExSet = new Set(from.topic.examples);
3
+ const toExSet = new Set(to.topic.examples);
4
+ const examplesAdded = to.topic.examples.filter((e) => !fromExSet.has(e));
5
+ const examplesRemoved = from.topic.examples.filter((e) => !toExSet.has(e));
6
+ return {
7
+ fromIteration: from.iteration,
8
+ toIteration: to.iteration,
9
+ descriptionChanged: from.topic.description !== to.topic.description,
10
+ examplesChanged: examplesAdded.length > 0 || examplesRemoved.length > 0,
11
+ examplesAdded,
12
+ examplesRemoved,
13
+ descriptionBefore: from.topic.description,
14
+ descriptionAfter: to.topic.description,
15
+ metricDelta: {
16
+ coverage: to.metrics.coverage - from.metrics.coverage,
17
+ tpr: to.metrics.truePositiveRate - from.metrics.truePositiveRate,
18
+ tnr: to.metrics.trueNegativeRate - from.metrics.trueNegativeRate,
19
+ accuracy: to.metrics.accuracy - from.metrics.accuracy,
20
+ f1: to.metrics.f1Score - from.metrics.f1Score,
21
+ },
22
+ };
23
+ }
24
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/memory/diff.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,oBAAoB,CAAC,IAAqB,EAAE,EAAmB;IAC7E,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE3C,MAAM,aAAa,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3E,OAAO;QACL,aAAa,EAAE,IAAI,CAAC,SAAS;QAC7B,WAAW,EAAE,EAAE,CAAC,SAAS;QACzB,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,EAAE,CAAC,KAAK,CAAC,WAAW;QACnE,eAAe,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC;QACvE,aAAa;QACb,eAAe;QACf,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW;QACzC,gBAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW;QACtC,WAAW,EAAE;YACX,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ;YACrD,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB;YAChE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB;YAChE,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ;YACrD,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO;SAC9C;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import type { RunState } from '../core/types.js';
3
+ import { type MemoryStore } from './store.js';
4
+ import type { Learning } from './types.js';
5
+ export declare class LearningExtractor {
6
+ private model;
7
+ private store;
8
+ constructor(model: BaseChatModel, store: MemoryStore);
9
+ extractAndSave(runState: RunState): Promise<{
10
+ learnings: Learning[];
11
+ }>;
12
+ private mergeLearnings;
13
+ private formatIterationHistory;
14
+ }
15
+ //# sourceMappingURL=extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/memory/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAEjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,YAAY,CAAC;AAExD,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,KAAK;gBADL,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,WAAW;IAGtB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,QAAQ,EAAE,CAAA;KAAE,CAAC;IAoF5E,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,sBAAsB;CAwC/B"}
@@ -0,0 +1,133 @@
1
+ import { nanoid } from 'nanoid';
2
+ import { computeIterationDiff } from './diff.js';
3
+ import { extractLearningsPrompt } from './prompts/extract-learnings.js';
4
+ import { LearningExtractionOutputSchema } from './schemas.js';
5
+ import { normalizeCategory } from './store.js';
6
+ export class LearningExtractor {
7
+ model;
8
+ store;
9
+ constructor(model, store) {
10
+ this.model = model;
11
+ this.store = store;
12
+ }
13
+ async extractAndSave(runState) {
14
+ if (runState.iterations.length < 1) {
15
+ return { learnings: [] };
16
+ }
17
+ const structured = this.model.withStructuredOutput(LearningExtractionOutputSchema);
18
+ const chain = extractLearningsPrompt.pipe(structured);
19
+ const iterationHistory = this.formatIterationHistory(runState);
20
+ const raw = (await chain.invoke({
21
+ topicDescription: runState.userInput.topicDescription,
22
+ intent: runState.userInput.intent,
23
+ totalIterations: runState.iterations.length,
24
+ bestIteration: runState.bestIteration,
25
+ bestCoverage: `${(runState.bestCoverage * 100).toFixed(1)}%`,
26
+ iterationHistory,
27
+ }));
28
+ const category = normalizeCategory(runState.userInput.topicDescription);
29
+ const bestIter = runState.iterations[runState.bestIteration - 1] ??
30
+ runState.iterations[runState.iterations.length - 1];
31
+ // Build learnings with metadata
32
+ const newLearnings = raw.learnings.map((l) => ({
33
+ id: nanoid(),
34
+ runId: runState.id,
35
+ extractedAt: new Date().toISOString(),
36
+ topicCategory: category,
37
+ topicDescription: runState.userInput.topicDescription,
38
+ insight: l.insight,
39
+ strategy: l.strategy,
40
+ outcome: l.outcome,
41
+ changeType: l.changeType,
42
+ metrics: {
43
+ coverage: bestIter.metrics.coverage,
44
+ tpr: bestIter.metrics.truePositiveRate,
45
+ tnr: bestIter.metrics.trueNegativeRate,
46
+ accuracy: bestIter.metrics.accuracy,
47
+ f1: bestIter.metrics.f1Score,
48
+ },
49
+ corroborations: 0,
50
+ tags: l.tags,
51
+ }));
52
+ // Merge into existing memory
53
+ const existing = (await this.store.load(category)) ?? {
54
+ category,
55
+ updatedAt: '',
56
+ learnings: [],
57
+ bestKnown: null,
58
+ antiPatterns: [],
59
+ };
60
+ const mergedLearnings = this.mergeLearnings(existing.learnings, newLearnings);
61
+ // Update bestKnown only if new run is better
62
+ let { bestKnown } = existing;
63
+ if (!bestKnown || runState.bestCoverage > bestKnown.metrics.coverage) {
64
+ bestKnown = {
65
+ runId: runState.id,
66
+ iteration: bestIter.iteration,
67
+ topic: bestIter.topic,
68
+ metrics: bestIter.metrics,
69
+ };
70
+ }
71
+ // Merge anti-patterns (deduplicate)
72
+ const antiPatternSet = new Set([...existing.antiPatterns, ...raw.antiPatterns]);
73
+ const memory = {
74
+ category,
75
+ updatedAt: new Date().toISOString(),
76
+ learnings: mergedLearnings,
77
+ bestKnown,
78
+ antiPatterns: [...antiPatternSet],
79
+ };
80
+ await this.store.save(memory);
81
+ return { learnings: newLearnings };
82
+ }
83
+ mergeLearnings(existing, incoming) {
84
+ const merged = [...existing];
85
+ for (const newL of incoming) {
86
+ const match = merged.findIndex((e) => e.insight === newL.insight);
87
+ if (match >= 0) {
88
+ // Corroborate: increment count, keep existing metrics
89
+ merged[match] = {
90
+ ...merged[match],
91
+ corroborations: merged[match].corroborations + 1,
92
+ extractedAt: newL.extractedAt,
93
+ };
94
+ }
95
+ else {
96
+ merged.push(newL);
97
+ }
98
+ }
99
+ return merged;
100
+ }
101
+ formatIterationHistory(runState) {
102
+ const lines = [];
103
+ for (let i = 0; i < runState.iterations.length; i++) {
104
+ const iter = runState.iterations[i];
105
+ lines.push(`--- Iteration ${iter.iteration} ---`);
106
+ lines.push(`Description: "${iter.topic.description}"`);
107
+ lines.push(`Example count: ${iter.topic.examples.length}`);
108
+ lines.push(`Examples: ${iter.topic.examples.length > 0 ? iter.topic.examples.map((e) => `"${e}"`).join(', ') : 'None (description-only)'}`);
109
+ lines.push(`Coverage: ${(iter.metrics.coverage * 100).toFixed(1)}% | TPR: ${(iter.metrics.truePositiveRate * 100).toFixed(1)}% | TNR: ${(iter.metrics.trueNegativeRate * 100).toFixed(1)}%`);
110
+ lines.push(`Analysis: ${iter.analysis.summary}`);
111
+ if (i > 0) {
112
+ const diff = computeIterationDiff(runState.iterations[i - 1], iter);
113
+ const changes = [];
114
+ if (diff.descriptionChanged)
115
+ changes.push('description changed');
116
+ if (diff.examplesChanged) {
117
+ const prevCount = runState.iterations[i - 1].topic.examples.length;
118
+ const currCount = iter.topic.examples.length;
119
+ changes.push(`example count: ${prevCount} → ${currCount}`);
120
+ if (diff.examplesAdded.length)
121
+ changes.push(`+examples: ${diff.examplesAdded.join(', ')}`);
122
+ if (diff.examplesRemoved.length)
123
+ changes.push(`-examples: ${diff.examplesRemoved.join(', ')}`);
124
+ }
125
+ lines.push(`Changes: ${changes.join('; ') || 'none'}`);
126
+ lines.push(`Coverage delta: ${diff.metricDelta.coverage >= 0 ? '+' : ''}${(diff.metricDelta.coverage * 100).toFixed(1)}%`);
127
+ }
128
+ lines.push('');
129
+ }
130
+ return lines.join('\n');
131
+ }
132
+ }
133
+ //# sourceMappingURL=extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/memory/extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { MemoryStore } from './store.js';
2
+ /**
3
+ * Builds a budget-aware memory section for LLM prompt injection.
4
+ * Retrieves relevant learnings from the store, sorts by corroboration count,
5
+ * and formats them within a character budget (verbose -> compact -> omit).
6
+ */
7
+ export declare class MemoryInjector {
8
+ private store;
9
+ private maxChars;
10
+ /**
11
+ * @param store - Memory store for retrieving learnings.
12
+ * @param maxChars - Character budget for the memory section. Default 3000.
13
+ */
14
+ constructor(store: MemoryStore, maxChars?: number);
15
+ /**
16
+ * Build a formatted memory section string for prompt injection.
17
+ * @param topicDescription - Topic to find relevant learnings for.
18
+ * @returns Formatted learnings string, or empty string if none found.
19
+ */
20
+ buildMemorySection(topicDescription: string): Promise<string>;
21
+ }
22
+ //# sourceMappingURL=injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injector.d.ts","sourceRoot":"","sources":["../../src/memory/injector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C;;;;GAIG;AACH,qBAAa,cAAc;IAMvB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;IANlB;;;OAGG;gBAEO,KAAK,EAAE,WAAW,EAClB,QAAQ,GAAE,MAAa;IAGjC;;;;OAIG;IACG,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA6EpE"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Builds a budget-aware memory section for LLM prompt injection.
3
+ * Retrieves relevant learnings from the store, sorts by corroboration count,
4
+ * and formats them within a character budget (verbose -> compact -> omit).
5
+ */
6
+ export class MemoryInjector {
7
+ store;
8
+ maxChars;
9
+ /**
10
+ * @param store - Memory store for retrieving learnings.
11
+ * @param maxChars - Character budget for the memory section. Default 3000.
12
+ */
13
+ constructor(store, maxChars = 3000) {
14
+ this.store = store;
15
+ this.maxChars = maxChars;
16
+ }
17
+ /**
18
+ * Build a formatted memory section string for prompt injection.
19
+ * @param topicDescription - Topic to find relevant learnings for.
20
+ * @returns Formatted learnings string, or empty string if none found.
21
+ */
22
+ async buildMemorySection(topicDescription) {
23
+ const memories = await this.store.findRelevant(topicDescription);
24
+ if (memories.length === 0)
25
+ return '';
26
+ const allLearnings = [];
27
+ const allAntiPatterns = [];
28
+ for (const mem of memories) {
29
+ allLearnings.push(...mem.learnings);
30
+ allAntiPatterns.push(...mem.antiPatterns);
31
+ }
32
+ if (allLearnings.length === 0 && allAntiPatterns.length === 0)
33
+ return '';
34
+ // Sort by corroborations descending
35
+ allLearnings.sort((a, b) => b.corroborations - a.corroborations);
36
+ const header = [
37
+ '\n## Learnings from Previous Runs',
38
+ 'These are empirically validated observations from prior guardrail generation runs:',
39
+ ];
40
+ // Budget for content after header; each added line costs lineLen + 1 (newline separator)
41
+ let budget = this.maxChars - header.join('\n').length;
42
+ const lines = [...header];
43
+ let compactMode = false;
44
+ let omitted = 0;
45
+ for (const l of allLearnings) {
46
+ const tag = l.outcome === 'degraded' ? 'AVOID' : 'DO';
47
+ const seenCount = l.corroborations + 1;
48
+ if (!compactMode) {
49
+ const verbose = `- [${tag}] ${l.insight} (${l.changeType}, seen ${seenCount}x)`;
50
+ if (verbose.length + 1 <= budget) {
51
+ lines.push(verbose);
52
+ budget -= verbose.length + 1; // +1 for newline
53
+ continue;
54
+ }
55
+ // Switch to compact mode
56
+ compactMode = true;
57
+ }
58
+ const compact = `- [${tag}] ${l.insight}`;
59
+ if (compact.length + 1 <= budget) {
60
+ lines.push(compact);
61
+ budget -= compact.length + 1;
62
+ }
63
+ else {
64
+ omitted++;
65
+ }
66
+ }
67
+ if (omitted > 0) {
68
+ const notice = `(+${omitted} more learnings omitted)`;
69
+ if (notice.length + 1 <= budget) {
70
+ lines.push(notice);
71
+ budget -= notice.length + 1;
72
+ }
73
+ }
74
+ const uniqueAntiPatterns = [...new Set(allAntiPatterns)];
75
+ if (uniqueAntiPatterns.length > 0) {
76
+ lines.push('');
77
+ lines.push('Known anti-patterns:');
78
+ budget -= 1 + 'Known anti-patterns:'.length + 1; // blank line + header
79
+ for (const ap of uniqueAntiPatterns) {
80
+ const line = `- ${ap}`;
81
+ if (line.length + 1 <= budget) {
82
+ lines.push(line);
83
+ budget -= line.length + 1;
84
+ }
85
+ }
86
+ }
87
+ return lines.join('\n');
88
+ }
89
+ }
90
+ //# sourceMappingURL=injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injector.js","sourceRoot":"","sources":["../../src/memory/injector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { ChatPromptTemplate } from '@langchain/core/prompts';
2
+ export declare const extractLearningsPrompt: ChatPromptTemplate<any, any>;
3
+ //# sourceMappingURL=extract-learnings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-learnings.d.ts","sourceRoot":"","sources":["../../../src/memory/prompts/extract-learnings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,eAAO,MAAM,sBAAsB,8BAqCjC,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { ChatPromptTemplate } from '@langchain/core/prompts';
2
+ export const extractLearningsPrompt = ChatPromptTemplate.fromMessages([
3
+ [
4
+ 'system',
5
+ `You are analyzing the results of a Prisma AIRS custom topic guardrail generation run to extract reusable learnings.
6
+
7
+ Given the iteration history, identify:
8
+ 1. **Learnings**: What worked, what didn't, and why. Each learning should have:
9
+ - insight: A concise observation (e.g., "Short direct descriptions outperform nuanced ones on AIRS")
10
+ - strategy: What was actually done (e.g., "Used a short description without exclusion clauses")
11
+ - outcome: "improved", "degraded", or "neutral"
12
+ - changeType: "description-only", "examples-only", "both", or "initial"
13
+ - tags: keywords like "brevity", "coded-language", "fp-reduction", "fn-reduction", "exclusion-clauses", "example-count", "zero-examples", "description-weight"
14
+
15
+ 2. **Anti-patterns**: Strategies that consistently degraded performance (e.g., "Adding coded language patterns broadens AIRS matching unpredictably")
16
+
17
+ Pay special attention to the RELATIONSHIP BETWEEN EXAMPLE COUNT AND EFFICACY:
18
+ - Track whether reducing examples improved or degraded metrics
19
+ - Note when fewer examples (2) outperformed configurations with more examples (3-5)
20
+ - Identify if specific example counts (2, 3, 4, 5) correlate with better coverage for this topic type
21
+ - Tag learnings about example count with "example-count" and the relevant count (e.g., "few-examples", "many-examples")
22
+
23
+ Focus on actionable, generalizable insights. Avoid restating metrics — explain the *why* behind changes.`,
24
+ ],
25
+ [
26
+ 'human',
27
+ `Analyze this guardrail generation run:
28
+
29
+ Topic Description: {topicDescription}
30
+ Intent: {intent}
31
+ Total Iterations: {totalIterations}
32
+ Best Iteration: {bestIteration} (coverage: {bestCoverage})
33
+
34
+ Iteration History:
35
+ {iterationHistory}
36
+
37
+ Extract structured learnings from this run.`,
38
+ ],
39
+ ]);
40
+ //# sourceMappingURL=extract-learnings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-learnings.js","sourceRoot":"","sources":["../../../src/memory/prompts/extract-learnings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,CAAC,MAAM,sBAAsB,GAAG,kBAAkB,CAAC,YAAY,CAAC;IACpE;QACE,QAAQ;QACR;;;;;;;;;;;;;;;;;;yGAkBqG;KACtG;IACD;QACE,OAAO;QACP;;;;;;;;;;4CAUwC;KACzC;CACF,CAAC,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { z } from 'zod';
2
+ export declare const ExtractedLearningSchema: z.ZodObject<{
3
+ insight: z.ZodString;
4
+ strategy: z.ZodString;
5
+ outcome: z.ZodEnum<["improved", "degraded", "neutral"]>;
6
+ changeType: z.ZodEnum<["description-only", "examples-only", "both", "initial"]>;
7
+ tags: z.ZodArray<z.ZodString, "many">;
8
+ }, "strip", z.ZodTypeAny, {
9
+ insight: string;
10
+ strategy: string;
11
+ outcome: "improved" | "degraded" | "neutral";
12
+ changeType: "description-only" | "examples-only" | "both" | "initial";
13
+ tags: string[];
14
+ }, {
15
+ insight: string;
16
+ strategy: string;
17
+ outcome: "improved" | "degraded" | "neutral";
18
+ changeType: "description-only" | "examples-only" | "both" | "initial";
19
+ tags: string[];
20
+ }>;
21
+ export declare const LearningExtractionOutputSchema: z.ZodObject<{
22
+ learnings: z.ZodArray<z.ZodObject<{
23
+ insight: z.ZodString;
24
+ strategy: z.ZodString;
25
+ outcome: z.ZodEnum<["improved", "degraded", "neutral"]>;
26
+ changeType: z.ZodEnum<["description-only", "examples-only", "both", "initial"]>;
27
+ tags: z.ZodArray<z.ZodString, "many">;
28
+ }, "strip", z.ZodTypeAny, {
29
+ insight: string;
30
+ strategy: string;
31
+ outcome: "improved" | "degraded" | "neutral";
32
+ changeType: "description-only" | "examples-only" | "both" | "initial";
33
+ tags: string[];
34
+ }, {
35
+ insight: string;
36
+ strategy: string;
37
+ outcome: "improved" | "degraded" | "neutral";
38
+ changeType: "description-only" | "examples-only" | "both" | "initial";
39
+ tags: string[];
40
+ }>, "many">;
41
+ antiPatterns: z.ZodArray<z.ZodString, "many">;
42
+ }, "strip", z.ZodTypeAny, {
43
+ learnings: {
44
+ insight: string;
45
+ strategy: string;
46
+ outcome: "improved" | "degraded" | "neutral";
47
+ changeType: "description-only" | "examples-only" | "both" | "initial";
48
+ tags: string[];
49
+ }[];
50
+ antiPatterns: string[];
51
+ }, {
52
+ learnings: {
53
+ insight: string;
54
+ strategy: string;
55
+ outcome: "improved" | "degraded" | "neutral";
56
+ changeType: "description-only" | "examples-only" | "both" | "initial";
57
+ tags: string[];
58
+ }[];
59
+ antiPatterns: string[];
60
+ }>;
61
+ export type ExtractedLearning = z.infer<typeof ExtractedLearningSchema>;
62
+ export type LearningExtractionOutput = z.infer<typeof LearningExtractionOutputSchema>;
63
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/memory/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;EAMlC,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGzC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ export const ExtractedLearningSchema = z.object({
3
+ insight: z.string().min(1),
4
+ strategy: z.string().min(1),
5
+ outcome: z.enum(['improved', 'degraded', 'neutral']),
6
+ changeType: z.enum(['description-only', 'examples-only', 'both', 'initial']),
7
+ tags: z.array(z.string()),
8
+ });
9
+ export const LearningExtractionOutputSchema = z.object({
10
+ learnings: z.array(ExtractedLearningSchema),
11
+ antiPatterns: z.array(z.string()),
12
+ });
13
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/memory/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACpD,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,kBAAkB,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAC5E,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAC1B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,MAAM,CAAC;IACrD,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC;IAC3C,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAClC,CAAC,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { TopicMemory } from './types.js';
2
+ /**
3
+ * Normalize a topic description into a stable category key.
4
+ * Removes stop words, lowercases, deduplicates, and sorts alphabetically.
5
+ * @param description - Free-text topic description.
6
+ * @returns Hyphen-joined keyword string used as the memory file name.
7
+ */
8
+ export declare function normalizeCategory(description: string): string;
9
+ /**
10
+ * File-based persistence for cross-run learnings.
11
+ * Stores one JSON file per category at `{dir}/{category}.json`.
12
+ * Supports keyword-overlap-based retrieval for cross-topic transfer.
13
+ */
14
+ export declare class MemoryStore {
15
+ private dir;
16
+ constructor(dir: string);
17
+ private filePath;
18
+ /** Persist a topic memory to disk, creating the directory if needed. */
19
+ save(memory: TopicMemory): Promise<void>;
20
+ /** Load a topic memory by category, or null if not found. */
21
+ load(category: string): Promise<TopicMemory | null>;
22
+ /** Find all topic memories with >= 50% keyword overlap to the given description. */
23
+ findRelevant(topicDescription: string): Promise<TopicMemory[]>;
24
+ /** List all stored category names. */
25
+ listCategories(): Promise<string[]>;
26
+ private categoriesOverlap;
27
+ }
28
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAuB9C;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAS7D;AAED;;;;GAIG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,MAAM;IAE/B,OAAO,CAAC,QAAQ;IAIhB,wEAAwE;IAClE,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9C,6DAA6D;IACvD,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IASzD,oFAAoF;IAC9E,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAepE,sCAAsC;IAChC,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IASzC,OAAO,CAAC,iBAAiB;CAW1B"}
@@ -0,0 +1,103 @@
1
+ import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ const STOP_WORDS = new Set([
4
+ 'a',
5
+ 'an',
6
+ 'the',
7
+ 'and',
8
+ 'or',
9
+ 'of',
10
+ 'about',
11
+ 'for',
12
+ 'in',
13
+ 'on',
14
+ 'to',
15
+ 'with',
16
+ 'that',
17
+ 'this',
18
+ 'is',
19
+ 'are',
20
+ 'was',
21
+ 'were',
22
+ ]);
23
+ /**
24
+ * Normalize a topic description into a stable category key.
25
+ * Removes stop words, lowercases, deduplicates, and sorts alphabetically.
26
+ * @param description - Free-text topic description.
27
+ * @returns Hyphen-joined keyword string used as the memory file name.
28
+ */
29
+ export function normalizeCategory(description) {
30
+ const words = description
31
+ .toLowerCase()
32
+ .replace(/[^a-z0-9\s]/g, '')
33
+ .split(/\s+/)
34
+ .filter((w) => w.length > 0 && !STOP_WORDS.has(w));
35
+ const unique = [...new Set(words)].sort();
36
+ return unique.length > 0 ? unique.join('-') : 'uncategorized';
37
+ }
38
+ /**
39
+ * File-based persistence for cross-run learnings.
40
+ * Stores one JSON file per category at `{dir}/{category}.json`.
41
+ * Supports keyword-overlap-based retrieval for cross-topic transfer.
42
+ */
43
+ export class MemoryStore {
44
+ dir;
45
+ constructor(dir) {
46
+ this.dir = dir;
47
+ }
48
+ filePath(category) {
49
+ return join(this.dir, `${category}.json`);
50
+ }
51
+ /** Persist a topic memory to disk, creating the directory if needed. */
52
+ async save(memory) {
53
+ await mkdir(this.dir, { recursive: true });
54
+ await writeFile(this.filePath(memory.category), JSON.stringify(memory, null, 2), 'utf-8');
55
+ }
56
+ /** Load a topic memory by category, or null if not found. */
57
+ async load(category) {
58
+ try {
59
+ const data = await readFile(this.filePath(category), 'utf-8');
60
+ return JSON.parse(data);
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ }
66
+ /** Find all topic memories with >= 50% keyword overlap to the given description. */
67
+ async findRelevant(topicDescription) {
68
+ const targetCategory = normalizeCategory(topicDescription);
69
+ const categories = await this.listCategories();
70
+ const results = [];
71
+ for (const cat of categories) {
72
+ if (this.categoriesOverlap(targetCategory, cat)) {
73
+ const memory = await this.load(cat);
74
+ if (memory)
75
+ results.push(memory);
76
+ }
77
+ }
78
+ return results;
79
+ }
80
+ /** List all stored category names. */
81
+ async listCategories() {
82
+ try {
83
+ const files = await readdir(this.dir);
84
+ return files.filter((f) => f.endsWith('.json')).map((f) => f.replace(/\.json$/, ''));
85
+ }
86
+ catch {
87
+ return [];
88
+ }
89
+ }
90
+ categoriesOverlap(a, b) {
91
+ const wordsA = new Set(a.split('-'));
92
+ const wordsB = new Set(b.split('-'));
93
+ let overlap = 0;
94
+ for (const w of wordsA) {
95
+ if (wordsB.has(w))
96
+ overlap++;
97
+ }
98
+ // Require at least 50% keyword overlap relative to smaller set
99
+ const minSize = Math.min(wordsA.size, wordsB.size);
100
+ return minSize > 0 && overlap / minSize >= 0.5;
101
+ }
102
+ }
103
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"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"}