@cdot65/daystrom 1.0.3

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 (134) hide show
  1. package/README.md +93 -0
  2. package/dist/airs/management.d.ts +21 -0
  3. package/dist/airs/management.d.ts.map +1 -0
  4. package/dist/airs/management.js +78 -0
  5. package/dist/airs/management.js.map +1 -0
  6. package/dist/airs/scanner.d.ts +8 -0
  7. package/dist/airs/scanner.d.ts.map +1 -0
  8. package/dist/airs/scanner.js +28 -0
  9. package/dist/airs/scanner.js.map +1 -0
  10. package/dist/airs/types.d.ts +26 -0
  11. package/dist/airs/types.d.ts.map +1 -0
  12. package/dist/airs/types.js +6 -0
  13. package/dist/airs/types.js.map +1 -0
  14. package/dist/cli/commands/generate.d.ts +3 -0
  15. package/dist/cli/commands/generate.d.ts.map +1 -0
  16. package/dist/cli/commands/generate.js +127 -0
  17. package/dist/cli/commands/generate.js.map +1 -0
  18. package/dist/cli/commands/list.d.ts +3 -0
  19. package/dist/cli/commands/list.d.ts.map +1 -0
  20. package/dist/cli/commands/list.js +22 -0
  21. package/dist/cli/commands/list.js.map +1 -0
  22. package/dist/cli/commands/report.d.ts +3 -0
  23. package/dist/cli/commands/report.d.ts.map +1 -0
  24. package/dist/cli/commands/report.js +57 -0
  25. package/dist/cli/commands/report.js.map +1 -0
  26. package/dist/cli/commands/resume.d.ts +3 -0
  27. package/dist/cli/commands/resume.d.ts.map +1 -0
  28. package/dist/cli/commands/resume.js +95 -0
  29. package/dist/cli/commands/resume.js.map +1 -0
  30. package/dist/cli/index.d.ts +3 -0
  31. package/dist/cli/index.d.ts.map +1 -0
  32. package/dist/cli/index.js +18 -0
  33. package/dist/cli/index.js.map +1 -0
  34. package/dist/cli/prompts.d.ts +6 -0
  35. package/dist/cli/prompts.d.ts.map +1 -0
  36. package/dist/cli/prompts.js +72 -0
  37. package/dist/cli/prompts.js.map +1 -0
  38. package/dist/cli/renderer.d.ts +15 -0
  39. package/dist/cli/renderer.d.ts.map +1 -0
  40. package/dist/cli/renderer.js +103 -0
  41. package/dist/cli/renderer.js.map +1 -0
  42. package/dist/config/loader.d.ts +3 -0
  43. package/dist/config/loader.d.ts.map +1 -0
  44. package/dist/config/loader.js +63 -0
  45. package/dist/config/loader.js.map +1 -0
  46. package/dist/config/schema.d.ts +72 -0
  47. package/dist/config/schema.d.ts.map +1 -0
  48. package/dist/config/schema.js +42 -0
  49. package/dist/config/schema.js.map +1 -0
  50. package/dist/core/constraints.d.ts +16 -0
  51. package/dist/core/constraints.d.ts.map +1 -0
  52. package/dist/core/constraints.js +77 -0
  53. package/dist/core/constraints.js.map +1 -0
  54. package/dist/core/loop.d.ts +23 -0
  55. package/dist/core/loop.d.ts.map +1 -0
  56. package/dist/core/loop.js +146 -0
  57. package/dist/core/loop.js.map +1 -0
  58. package/dist/core/metrics.d.ts +3 -0
  59. package/dist/core/metrics.d.ts.map +1 -0
  60. package/dist/core/metrics.js +38 -0
  61. package/dist/core/metrics.js.map +1 -0
  62. package/dist/core/types.d.ts +104 -0
  63. package/dist/core/types.d.ts.map +1 -0
  64. package/dist/core/types.js +5 -0
  65. package/dist/core/types.js.map +1 -0
  66. package/dist/index.d.ts +23 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +34 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/llm/prompts/analyze-results.d.ts +3 -0
  71. package/dist/llm/prompts/analyze-results.d.ts.map +1 -0
  72. package/dist/llm/prompts/analyze-results.js +38 -0
  73. package/dist/llm/prompts/analyze-results.js.map +1 -0
  74. package/dist/llm/prompts/generate-tests.d.ts +3 -0
  75. package/dist/llm/prompts/generate-tests.d.ts.map +1 -0
  76. package/dist/llm/prompts/generate-tests.js +33 -0
  77. package/dist/llm/prompts/generate-tests.js.map +1 -0
  78. package/dist/llm/prompts/generate-topic.d.ts +4 -0
  79. package/dist/llm/prompts/generate-topic.d.ts.map +1 -0
  80. package/dist/llm/prompts/generate-topic.js +32 -0
  81. package/dist/llm/prompts/generate-topic.js.map +1 -0
  82. package/dist/llm/prompts/improve-topic.d.ts +3 -0
  83. package/dist/llm/prompts/improve-topic.d.ts.map +1 -0
  84. package/dist/llm/prompts/improve-topic.js +50 -0
  85. package/dist/llm/prompts/improve-topic.js.map +1 -0
  86. package/dist/llm/provider.d.ts +15 -0
  87. package/dist/llm/provider.d.ts.map +1 -0
  88. package/dist/llm/provider.js +71 -0
  89. package/dist/llm/provider.js.map +1 -0
  90. package/dist/llm/schemas.d.ts +97 -0
  91. package/dist/llm/schemas.d.ts.map +1 -0
  92. package/dist/llm/schemas.js +22 -0
  93. package/dist/llm/schemas.js.map +1 -0
  94. package/dist/llm/service.d.ts +19 -0
  95. package/dist/llm/service.d.ts.map +1 -0
  96. package/dist/llm/service.js +177 -0
  97. package/dist/llm/service.js.map +1 -0
  98. package/dist/memory/diff.d.ts +4 -0
  99. package/dist/memory/diff.d.ts.map +1 -0
  100. package/dist/memory/diff.js +24 -0
  101. package/dist/memory/diff.js.map +1 -0
  102. package/dist/memory/extractor.d.ts +15 -0
  103. package/dist/memory/extractor.d.ts.map +1 -0
  104. package/dist/memory/extractor.js +129 -0
  105. package/dist/memory/extractor.js.map +1 -0
  106. package/dist/memory/injector.d.ts +8 -0
  107. package/dist/memory/injector.d.ts.map +1 -0
  108. package/dist/memory/injector.js +76 -0
  109. package/dist/memory/injector.js.map +1 -0
  110. package/dist/memory/prompts/extract-learnings.d.ts +3 -0
  111. package/dist/memory/prompts/extract-learnings.d.ts.map +1 -0
  112. package/dist/memory/prompts/extract-learnings.js +34 -0
  113. package/dist/memory/prompts/extract-learnings.js.map +1 -0
  114. package/dist/memory/schemas.d.ts +63 -0
  115. package/dist/memory/schemas.d.ts.map +1 -0
  116. package/dist/memory/schemas.js +13 -0
  117. package/dist/memory/schemas.js.map +1 -0
  118. package/dist/memory/store.d.ts +13 -0
  119. package/dist/memory/store.d.ts.map +1 -0
  120. package/dist/memory/store.js +88 -0
  121. package/dist/memory/store.js.map +1 -0
  122. package/dist/memory/types.d.ts +55 -0
  123. package/dist/memory/types.d.ts.map +1 -0
  124. package/dist/memory/types.js +6 -0
  125. package/dist/memory/types.js.map +1 -0
  126. package/dist/persistence/store.d.ts +12 -0
  127. package/dist/persistence/store.d.ts.map +1 -0
  128. package/dist/persistence/store.js +68 -0
  129. package/dist/persistence/store.js.map +1 -0
  130. package/dist/persistence/types.d.ts +17 -0
  131. package/dist/persistence/types.d.ts.map +1 -0
  132. package/dist/persistence/types.js +2 -0
  133. package/dist/persistence/types.js.map +1 -0
  134. package/package.json +65 -0
@@ -0,0 +1,129 @@
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 the better 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(`Examples: ${iter.topic.examples.map((e) => `"${e}"`).join(', ')}`);
108
+ lines.push(`Coverage: ${(iter.metrics.coverage * 100).toFixed(1)}% | TPR: ${(iter.metrics.truePositiveRate * 100).toFixed(1)}% | TNR: ${(iter.metrics.trueNegativeRate * 100).toFixed(1)}%`);
109
+ lines.push(`Analysis: ${iter.analysis.summary}`);
110
+ if (i > 0) {
111
+ const diff = computeIterationDiff(runState.iterations[i - 1], iter);
112
+ const changes = [];
113
+ if (diff.descriptionChanged)
114
+ changes.push('description changed');
115
+ if (diff.examplesChanged) {
116
+ if (diff.examplesAdded.length)
117
+ changes.push(`+examples: ${diff.examplesAdded.join(', ')}`);
118
+ if (diff.examplesRemoved.length)
119
+ changes.push(`-examples: ${diff.examplesRemoved.join(', ')}`);
120
+ }
121
+ lines.push(`Changes: ${changes.join('; ') || 'none'}`);
122
+ lines.push(`Coverage delta: ${diff.metricDelta.coverage >= 0 ? '+' : ''}${(diff.metricDelta.coverage * 100).toFixed(1)}%`);
123
+ }
124
+ lines.push('');
125
+ }
126
+ return lines.join('\n');
127
+ }
128
+ }
129
+ //# 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,8 @@
1
+ import type { MemoryStore } from './store.js';
2
+ export declare class MemoryInjector {
3
+ private store;
4
+ private maxChars;
5
+ constructor(store: MemoryStore, maxChars?: number);
6
+ buildMemorySection(topicDescription: string): Promise<string>;
7
+ }
8
+ //# 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,qBAAa,cAAc;IAEvB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;gBADR,KAAK,EAAE,WAAW,EAClB,QAAQ,GAAE,MAAa;IAG3B,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA6EpE"}
@@ -0,0 +1,76 @@
1
+ export class MemoryInjector {
2
+ store;
3
+ maxChars;
4
+ constructor(store, maxChars = 3000) {
5
+ this.store = store;
6
+ this.maxChars = maxChars;
7
+ }
8
+ async buildMemorySection(topicDescription) {
9
+ const memories = await this.store.findRelevant(topicDescription);
10
+ if (memories.length === 0)
11
+ return '';
12
+ const allLearnings = [];
13
+ const allAntiPatterns = [];
14
+ for (const mem of memories) {
15
+ allLearnings.push(...mem.learnings);
16
+ allAntiPatterns.push(...mem.antiPatterns);
17
+ }
18
+ if (allLearnings.length === 0 && allAntiPatterns.length === 0)
19
+ return '';
20
+ // Sort by corroborations descending
21
+ allLearnings.sort((a, b) => b.corroborations - a.corroborations);
22
+ const header = [
23
+ '\n## Learnings from Previous Runs',
24
+ 'These are empirically validated observations from prior guardrail generation runs:',
25
+ ];
26
+ // Budget for content after header; each added line costs lineLen + 1 (newline separator)
27
+ let budget = this.maxChars - header.join('\n').length;
28
+ const lines = [...header];
29
+ let compactMode = false;
30
+ let omitted = 0;
31
+ for (const l of allLearnings) {
32
+ const tag = l.outcome === 'degraded' ? 'AVOID' : 'DO';
33
+ const seenCount = l.corroborations + 1;
34
+ if (!compactMode) {
35
+ const verbose = `- [${tag}] ${l.insight} (${l.changeType}, seen ${seenCount}x)`;
36
+ if (verbose.length + 1 <= budget) {
37
+ lines.push(verbose);
38
+ budget -= verbose.length + 1; // +1 for newline
39
+ continue;
40
+ }
41
+ // Switch to compact mode
42
+ compactMode = true;
43
+ }
44
+ const compact = `- [${tag}] ${l.insight}`;
45
+ if (compact.length + 1 <= budget) {
46
+ lines.push(compact);
47
+ budget -= compact.length + 1;
48
+ }
49
+ else {
50
+ omitted++;
51
+ }
52
+ }
53
+ if (omitted > 0) {
54
+ const notice = `(+${omitted} more learnings omitted)`;
55
+ if (notice.length + 1 <= budget) {
56
+ lines.push(notice);
57
+ budget -= notice.length + 1;
58
+ }
59
+ }
60
+ const uniqueAntiPatterns = [...new Set(allAntiPatterns)];
61
+ if (uniqueAntiPatterns.length > 0) {
62
+ lines.push('');
63
+ lines.push('Known anti-patterns:');
64
+ budget -= 1 + 'Known anti-patterns:'.length + 1; // blank line + header
65
+ for (const ap of uniqueAntiPatterns) {
66
+ const line = `- ${ap}`;
67
+ if (line.length + 1 <= budget) {
68
+ lines.push(line);
69
+ budget -= line.length + 1;
70
+ }
71
+ }
72
+ }
73
+ return lines.join('\n');
74
+ }
75
+ }
76
+ //# sourceMappingURL=injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injector.js","sourceRoot":"","sources":["../../src/memory/injector.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,cAAc;IAEf;IACA;IAFV,YACU,KAAkB,EAClB,WAAmB,IAAI;QADvB,UAAK,GAAL,KAAK,CAAa;QAClB,aAAQ,GAAR,QAAQ,CAAe;IAC9B,CAAC;IAEJ,KAAK,CAAC,kBAAkB,CAAC,gBAAwB;QAC/C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;QACjE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAErC,MAAM,YAAY,GAAe,EAAE,CAAC;QACpC,MAAM,eAAe,GAAa,EAAE,CAAC;QAErC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,YAAY,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;YACpC,eAAe,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEzE,oCAAoC;QACpC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC;QAEjE,MAAM,MAAM,GAAG;YACb,mCAAmC;YACnC,oFAAoF;SACrF,CAAC;QACF,yFAAyF;QACzF,IAAI,MAAM,GAAG,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QAEtD,MAAM,KAAK,GAAa,CAAC,GAAG,MAAM,CAAC,CAAC;QACpC,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;YACtD,MAAM,SAAS,GAAG,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC;YAEvC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,UAAU,UAAU,SAAS,IAAI,CAAC;gBAChF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;oBACjC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACpB,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,iBAAiB;oBAC/C,SAAS;gBACX,CAAC;gBACD,yBAAyB;gBACzB,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;YAC1C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;gBACjC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACpB,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,KAAK,OAAO,0BAA0B,CAAC;YACtD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;gBAChC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACnB,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;QACzD,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,GAAG,sBAAsB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,sBAAsB;YAEvE,KAAK,MAAM,EAAE,IAAI,kBAAkB,EAAE,CAAC;gBACpC,MAAM,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;gBACvB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;oBAC9B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACjB,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC5B,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -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,8BA+BjC,CAAC"}
@@ -0,0 +1,34 @@
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"
14
+
15
+ 2. **Anti-patterns**: Strategies that consistently degraded performance (e.g., "Adding coded language patterns broadens AIRS matching unpredictably")
16
+
17
+ Focus on actionable, generalizable insights. Avoid restating metrics — explain the *why* behind changes.`,
18
+ ],
19
+ [
20
+ 'human',
21
+ `Analyze this guardrail generation run:
22
+
23
+ Topic Description: {topicDescription}
24
+ Intent: {intent}
25
+ Total Iterations: {totalIterations}
26
+ Best Iteration: {bestIteration} (coverage: {bestCoverage})
27
+
28
+ Iteration History:
29
+ {iterationHistory}
30
+
31
+ Extract structured learnings from this run.`,
32
+ ],
33
+ ]);
34
+ //# 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;;;;;;;;;;;;yGAYqG;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,13 @@
1
+ import type { TopicMemory } from './types.js';
2
+ export declare function normalizeCategory(description: string): string;
3
+ export declare class MemoryStore {
4
+ private dir;
5
+ constructor(dir: string);
6
+ private filePath;
7
+ save(memory: TopicMemory): Promise<void>;
8
+ load(category: string): Promise<TopicMemory | null>;
9
+ findRelevant(topicDescription: string): Promise<TopicMemory[]>;
10
+ listCategories(): Promise<string[]>;
11
+ private categoriesOverlap;
12
+ }
13
+ //# 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,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAS7D;AAED,qBAAa,WAAW;IACV,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,MAAM;IAE/B,OAAO,CAAC,QAAQ;IAIV,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IASnD,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAe9D,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IASzC,OAAO,CAAC,iBAAiB;CAW1B"}
@@ -0,0 +1,88 @@
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
+ export function normalizeCategory(description) {
24
+ const words = description
25
+ .toLowerCase()
26
+ .replace(/[^a-z0-9\s]/g, '')
27
+ .split(/\s+/)
28
+ .filter((w) => w.length > 0 && !STOP_WORDS.has(w));
29
+ const unique = [...new Set(words)].sort();
30
+ return unique.join('-');
31
+ }
32
+ export class MemoryStore {
33
+ dir;
34
+ constructor(dir) {
35
+ this.dir = dir;
36
+ }
37
+ filePath(category) {
38
+ return join(this.dir, `${category}.json`);
39
+ }
40
+ async save(memory) {
41
+ await mkdir(this.dir, { recursive: true });
42
+ await writeFile(this.filePath(memory.category), JSON.stringify(memory, null, 2), 'utf-8');
43
+ }
44
+ async load(category) {
45
+ try {
46
+ const data = await readFile(this.filePath(category), 'utf-8');
47
+ return JSON.parse(data);
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ async findRelevant(topicDescription) {
54
+ const targetCategory = normalizeCategory(topicDescription);
55
+ const categories = await this.listCategories();
56
+ const results = [];
57
+ for (const cat of categories) {
58
+ if (this.categoriesOverlap(targetCategory, cat)) {
59
+ const memory = await this.load(cat);
60
+ if (memory)
61
+ results.push(memory);
62
+ }
63
+ }
64
+ return results;
65
+ }
66
+ async listCategories() {
67
+ try {
68
+ const files = await readdir(this.dir);
69
+ return files.filter((f) => f.endsWith('.json')).map((f) => f.replace(/\.json$/, ''));
70
+ }
71
+ catch {
72
+ return [];
73
+ }
74
+ }
75
+ categoriesOverlap(a, b) {
76
+ const wordsA = new Set(a.split('-'));
77
+ const wordsB = new Set(b.split('-'));
78
+ let overlap = 0;
79
+ for (const w of wordsA) {
80
+ if (wordsB.has(w))
81
+ overlap++;
82
+ }
83
+ // Require at least 50% keyword overlap relative to smaller set
84
+ const minSize = Math.min(wordsA.size, wordsB.size);
85
+ return minSize > 0 && overlap / minSize >= 0.5;
86
+ }
87
+ }
88
+ //# 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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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Memory system types — cross-run learning persistence that lets
3
+ * future runs benefit from past refinement insights.
4
+ */
5
+ import type { CustomTopic, EfficacyMetrics } from '../core/types.js';
6
+ export interface IterationDiff {
7
+ fromIteration: number;
8
+ toIteration: number;
9
+ descriptionChanged: boolean;
10
+ examplesChanged: boolean;
11
+ examplesAdded: string[];
12
+ examplesRemoved: string[];
13
+ descriptionBefore: string;
14
+ descriptionAfter: string;
15
+ metricDelta: {
16
+ coverage: number;
17
+ tpr: number;
18
+ tnr: number;
19
+ accuracy: number;
20
+ f1: number;
21
+ };
22
+ }
23
+ export interface Learning {
24
+ id: string;
25
+ runId: string;
26
+ extractedAt: string;
27
+ topicCategory: string;
28
+ topicDescription: string;
29
+ insight: string;
30
+ strategy: string;
31
+ outcome: 'improved' | 'degraded' | 'neutral';
32
+ changeType: 'description-only' | 'examples-only' | 'both' | 'initial';
33
+ metrics: {
34
+ coverage: number;
35
+ tpr: number;
36
+ tnr: number;
37
+ accuracy: number;
38
+ f1: number;
39
+ };
40
+ corroborations: number;
41
+ tags: string[];
42
+ }
43
+ export interface TopicMemory {
44
+ category: string;
45
+ updatedAt: string;
46
+ learnings: Learning[];
47
+ bestKnown: {
48
+ runId: string;
49
+ iteration: number;
50
+ topic: CustomTopic;
51
+ metrics: EfficacyMetrics;
52
+ } | null;
53
+ antiPatterns: string[];
54
+ }
55
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAKrE,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;CACH;AAKD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IAC7C,UAAU,EAAE,kBAAkB,GAAG,eAAe,GAAG,MAAM,GAAG,SAAS,CAAC;IACtE,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAKD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,SAAS,EAAE;QACT,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,WAAW,CAAC;QACnB,OAAO,EAAE,eAAe,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Memory system types — cross-run learning persistence that lets
3
+ * future runs benefit from past refinement insights.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,12 @@
1
+ import type { RunState } from '../core/types.js';
2
+ import type { RunStateSummary, RunStore } from './types.js';
3
+ export declare class JsonFileStore implements RunStore {
4
+ private readonly dir;
5
+ constructor(dir: string);
6
+ save(run: RunState): Promise<void>;
7
+ load(id: string): Promise<RunState | null>;
8
+ list(): Promise<RunStateSummary[]>;
9
+ delete(id: string): Promise<void>;
10
+ private filePath;
11
+ }
12
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/persistence/store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE5D,qBAAa,aAAc,YAAW,QAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,MAAM;IAElC,IAAI,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IASlC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAS1C,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IA8BlC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvC,OAAO,CAAC,QAAQ;CAGjB"}
@@ -0,0 +1,68 @@
1
+ import { mkdir, readdir, readFile, unlink, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ export class JsonFileStore {
4
+ dir;
5
+ constructor(dir) {
6
+ this.dir = dir;
7
+ }
8
+ async save(run) {
9
+ await mkdir(this.dir, { recursive: true });
10
+ const filePath = this.filePath(run.id);
11
+ const tmp = `${filePath}.tmp`;
12
+ await writeFile(tmp, JSON.stringify(run, null, 2), 'utf-8');
13
+ await writeFile(filePath, JSON.stringify(run, null, 2), 'utf-8');
14
+ await unlink(tmp).catch(() => { });
15
+ }
16
+ async load(id) {
17
+ try {
18
+ const data = await readFile(this.filePath(id), 'utf-8');
19
+ return JSON.parse(data);
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ async list() {
26
+ let files;
27
+ try {
28
+ files = await readdir(this.dir);
29
+ }
30
+ catch {
31
+ return [];
32
+ }
33
+ const summaries = [];
34
+ for (const file of files) {
35
+ if (!file.endsWith('.json'))
36
+ continue;
37
+ try {
38
+ const data = await readFile(join(this.dir, file), 'utf-8');
39
+ const run = JSON.parse(data);
40
+ summaries.push({
41
+ id: run.id,
42
+ createdAt: run.createdAt,
43
+ updatedAt: run.updatedAt,
44
+ status: run.status,
45
+ currentIteration: run.currentIteration,
46
+ bestCoverage: run.bestCoverage,
47
+ topicDescription: run.userInput.topicDescription,
48
+ });
49
+ }
50
+ catch {
51
+ // skip corrupted files
52
+ }
53
+ }
54
+ return summaries;
55
+ }
56
+ async delete(id) {
57
+ try {
58
+ await unlink(this.filePath(id));
59
+ }
60
+ catch {
61
+ // ignore if doesn't exist
62
+ }
63
+ }
64
+ filePath(id) {
65
+ return join(this.dir, `${id}.json`);
66
+ }
67
+ }
68
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/persistence/store.ts"],"names":[],"mappings":"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"}