agentic-qe 1.7.0 → 1.8.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.
- package/.claude/skills/sherlock-review/SKILL.md +786 -0
- package/CHANGELOG.md +531 -0
- package/README.md +37 -21
- package/dist/agents/BaseAgent.d.ts +8 -10
- package/dist/agents/BaseAgent.d.ts.map +1 -1
- package/dist/agents/BaseAgent.js +41 -43
- package/dist/agents/BaseAgent.js.map +1 -1
- package/dist/agents/CoverageAnalyzerAgent.js +2 -2
- package/dist/agents/CoverageAnalyzerAgent.js.map +1 -1
- package/dist/agents/LearningAgent.d.ts +2 -2
- package/dist/agents/LearningAgent.d.ts.map +1 -1
- package/dist/agents/LearningAgent.js +4 -4
- package/dist/agents/LearningAgent.js.map +1 -1
- package/dist/agents/TestExecutorAgent.d.ts +9 -0
- package/dist/agents/TestExecutorAgent.d.ts.map +1 -1
- package/dist/agents/TestExecutorAgent.js +60 -0
- package/dist/agents/TestExecutorAgent.js.map +1 -1
- package/dist/agents/examples/batchAnalyze.d.ts +252 -0
- package/dist/agents/examples/batchAnalyze.d.ts.map +1 -0
- package/dist/agents/examples/batchAnalyze.js +259 -0
- package/dist/agents/examples/batchAnalyze.js.map +1 -0
- package/dist/agents/examples/batchGenerate.d.ts +153 -0
- package/dist/agents/examples/batchGenerate.d.ts.map +1 -0
- package/dist/agents/examples/batchGenerate.js +166 -0
- package/dist/agents/examples/batchGenerate.js.map +1 -0
- package/dist/agents/generateWithPII.d.ts +128 -0
- package/dist/agents/generateWithPII.d.ts.map +1 -0
- package/dist/agents/generateWithPII.js +175 -0
- package/dist/agents/generateWithPII.js.map +1 -0
- package/dist/cli/commands/init.d.ts +6 -3
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +51 -46
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/learn/index.d.ts +4 -0
- package/dist/cli/commands/learn/index.d.ts.map +1 -1
- package/dist/cli/commands/learn/index.js +57 -0
- package/dist/cli/commands/learn/index.js.map +1 -1
- package/dist/cli/index.js +14 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/memory/AgentDBManager.d.ts +5 -0
- package/dist/core/memory/AgentDBManager.d.ts.map +1 -1
- package/dist/core/memory/AgentDBManager.js +19 -1
- package/dist/core/memory/AgentDBManager.js.map +1 -1
- package/dist/core/memory/RealAgentDBAdapter.d.ts +8 -0
- package/dist/core/memory/RealAgentDBAdapter.d.ts.map +1 -1
- package/dist/core/memory/RealAgentDBAdapter.js +74 -17
- package/dist/core/memory/RealAgentDBAdapter.js.map +1 -1
- package/dist/core/memory/ReasoningBankAdapter.d.ts +4 -0
- package/dist/core/memory/ReasoningBankAdapter.d.ts.map +1 -1
- package/dist/core/memory/ReasoningBankAdapter.js +20 -0
- package/dist/core/memory/ReasoningBankAdapter.js.map +1 -1
- package/dist/core/memory/SwarmMemoryManager.d.ts +8 -0
- package/dist/core/memory/SwarmMemoryManager.d.ts.map +1 -1
- package/dist/core/memory/SwarmMemoryManager.js +33 -0
- package/dist/core/memory/SwarmMemoryManager.js.map +1 -1
- package/dist/learning/ImprovementLoop.js +2 -2
- package/dist/learning/ImprovementLoop.js.map +1 -1
- package/dist/learning/LearningEngine.d.ts +11 -7
- package/dist/learning/LearningEngine.d.ts.map +1 -1
- package/dist/learning/LearningEngine.js +156 -72
- package/dist/learning/LearningEngine.js.map +1 -1
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.d.ts +83 -0
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.d.ts.map +1 -0
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.js +130 -0
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.js.map +1 -0
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.d.ts +58 -0
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.d.ts.map +1 -0
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.js +84 -0
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.js.map +1 -0
- package/dist/mcp/handlers/filtered/index.d.ts +47 -0
- package/dist/mcp/handlers/filtered/index.d.ts.map +1 -0
- package/dist/mcp/handlers/filtered/index.js +63 -0
- package/dist/mcp/handlers/filtered/index.js.map +1 -0
- package/dist/mcp/handlers/filtered/performance-tester-filtered.d.ts +57 -0
- package/dist/mcp/handlers/filtered/performance-tester-filtered.d.ts.map +1 -0
- package/dist/mcp/handlers/filtered/performance-tester-filtered.js +83 -0
- package/dist/mcp/handlers/filtered/performance-tester-filtered.js.map +1 -0
- package/dist/mcp/handlers/filtered/quality-assessor-filtered.d.ts +57 -0
- package/dist/mcp/handlers/filtered/quality-assessor-filtered.d.ts.map +1 -0
- package/dist/mcp/handlers/filtered/quality-assessor-filtered.js +93 -0
- package/dist/mcp/handlers/filtered/quality-assessor-filtered.js.map +1 -0
- package/dist/mcp/handlers/filtered/security-scanner-filtered.d.ts +54 -0
- package/dist/mcp/handlers/filtered/security-scanner-filtered.d.ts.map +1 -0
- package/dist/mcp/handlers/filtered/security-scanner-filtered.js +73 -0
- package/dist/mcp/handlers/filtered/security-scanner-filtered.js.map +1 -0
- package/dist/mcp/handlers/filtered/test-executor-filtered.d.ts +61 -0
- package/dist/mcp/handlers/filtered/test-executor-filtered.d.ts.map +1 -0
- package/dist/mcp/handlers/filtered/test-executor-filtered.js +117 -0
- package/dist/mcp/handlers/filtered/test-executor-filtered.js.map +1 -0
- package/dist/mcp/handlers/phase2/Phase2Tools.js +2 -2
- package/dist/mcp/handlers/phase2/Phase2Tools.js.map +1 -1
- package/dist/mcp/tools/deprecated.d.ts +8 -8
- package/dist/scripts/backup-helper.d.ts +64 -0
- package/dist/scripts/backup-helper.d.ts.map +1 -0
- package/dist/scripts/backup-helper.js +251 -0
- package/dist/scripts/backup-helper.js.map +1 -0
- package/dist/scripts/migrate-with-backup.d.ts +15 -0
- package/dist/scripts/migrate-with-backup.d.ts.map +1 -0
- package/dist/scripts/migrate-with-backup.js +194 -0
- package/dist/scripts/migrate-with-backup.js.map +1 -0
- package/dist/security/pii-tokenization.d.ts +216 -0
- package/dist/security/pii-tokenization.d.ts.map +1 -0
- package/dist/security/pii-tokenization.js +325 -0
- package/dist/security/pii-tokenization.js.map +1 -0
- package/dist/utils/EmbeddingGenerator.d.ts +35 -0
- package/dist/utils/EmbeddingGenerator.d.ts.map +1 -0
- package/dist/utils/EmbeddingGenerator.js +72 -0
- package/dist/utils/EmbeddingGenerator.js.map +1 -0
- package/dist/utils/batch-operations.d.ts +215 -0
- package/dist/utils/batch-operations.d.ts.map +1 -0
- package/dist/utils/batch-operations.js +266 -0
- package/dist/utils/batch-operations.js.map +1 -0
- package/dist/utils/filtering.d.ts +180 -0
- package/dist/utils/filtering.d.ts.map +1 -0
- package/dist/utils/filtering.js +288 -0
- package/dist/utils/filtering.js.map +1 -0
- package/dist/utils/prompt-cache-examples.d.ts +111 -0
- package/dist/utils/prompt-cache-examples.d.ts.map +1 -0
- package/dist/utils/prompt-cache-examples.js +416 -0
- package/dist/utils/prompt-cache-examples.js.map +1 -0
- package/dist/utils/prompt-cache.d.ts +305 -0
- package/dist/utils/prompt-cache.d.ts.map +1 -0
- package/dist/utils/prompt-cache.js +448 -0
- package/dist/utils/prompt-cache.js.map +1 -0
- package/package.json +6 -3
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Prompt Cache Integration Examples (CO-1)
|
|
4
|
+
*
|
|
5
|
+
* Demonstrates how to integrate PromptCacheManager with QE agents:
|
|
6
|
+
* - qe-test-generator
|
|
7
|
+
* - qe-coverage-analyzer
|
|
8
|
+
* - qe-security-scanner
|
|
9
|
+
*
|
|
10
|
+
* These examples show:
|
|
11
|
+
* - Proper system prompt caching
|
|
12
|
+
* - Project context caching
|
|
13
|
+
* - Cache statistics tracking
|
|
14
|
+
* - Cost savings monitoring
|
|
15
|
+
*
|
|
16
|
+
* @module utils/prompt-cache-examples
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.generateTestsWithCache = generateTestsWithCache;
|
|
20
|
+
exports.analyzeCoverageWithCache = analyzeCoverageWithCache;
|
|
21
|
+
exports.scanSecurityWithCache = scanSecurityWithCache;
|
|
22
|
+
exports.batchGenerateTestsWithCacheMonitoring = batchGenerateTestsWithCacheMonitoring;
|
|
23
|
+
exports.setupCacheMaintenance = setupCacheMaintenance;
|
|
24
|
+
exports.setupDailyStatsReset = setupDailyStatsReset;
|
|
25
|
+
const prompt_cache_1 = require("./prompt-cache");
|
|
26
|
+
/**
|
|
27
|
+
* System prompt for Test Generator Agent
|
|
28
|
+
*
|
|
29
|
+
* This is a large system prompt (>1024 tokens) that defines the agent's
|
|
30
|
+
* behavior and capabilities. Perfect candidate for caching.
|
|
31
|
+
*/
|
|
32
|
+
const TEST_GENERATOR_SYSTEM_PROMPT = `
|
|
33
|
+
You are an expert Test Generator Agent specialized in creating high-quality, comprehensive test suites.
|
|
34
|
+
|
|
35
|
+
Your capabilities include:
|
|
36
|
+
1. Generating unit tests, integration tests, and E2E tests
|
|
37
|
+
2. Optimizing test coverage using sublinear algorithms (O(log n))
|
|
38
|
+
3. Identifying edge cases and boundary conditions
|
|
39
|
+
4. Creating parameterized tests for reusability
|
|
40
|
+
5. Following testing best practices (AAA, DRY, FIRST principles)
|
|
41
|
+
|
|
42
|
+
When generating tests:
|
|
43
|
+
- Analyze code complexity and structure
|
|
44
|
+
- Identify critical paths and edge cases
|
|
45
|
+
- Generate diverse test scenarios
|
|
46
|
+
- Use appropriate assertions
|
|
47
|
+
- Follow framework-specific conventions (Jest, Vitest, etc.)
|
|
48
|
+
- Optimize for maximum coverage with minimum tests
|
|
49
|
+
|
|
50
|
+
Your test generation follows these principles:
|
|
51
|
+
- Tests should be deterministic and repeatable
|
|
52
|
+
- Tests should be isolated and independent
|
|
53
|
+
- Tests should have clear, descriptive names
|
|
54
|
+
- Tests should follow the Arrange-Act-Assert pattern
|
|
55
|
+
- Tests should cover happy paths, error cases, and edge cases
|
|
56
|
+
|
|
57
|
+
Format your test output as valid TypeScript/JavaScript code compatible with the specified framework.
|
|
58
|
+
`.trim();
|
|
59
|
+
/**
|
|
60
|
+
* System prompt for Coverage Analyzer Agent
|
|
61
|
+
*/
|
|
62
|
+
const COVERAGE_ANALYZER_SYSTEM_PROMPT = `
|
|
63
|
+
You are an expert Coverage Analyzer Agent specialized in identifying gaps in test coverage.
|
|
64
|
+
|
|
65
|
+
Your capabilities include:
|
|
66
|
+
1. Analyzing code coverage reports (lcov, istanbul, etc.)
|
|
67
|
+
2. Identifying untested code paths using O(log n) sublinear search
|
|
68
|
+
3. Prioritizing coverage gaps by risk and impact
|
|
69
|
+
4. Recommending specific tests to close gaps
|
|
70
|
+
5. Calculating coverage metrics and projections
|
|
71
|
+
|
|
72
|
+
When analyzing coverage:
|
|
73
|
+
- Parse coverage data from multiple formats
|
|
74
|
+
- Identify critical uncovered paths
|
|
75
|
+
- Calculate branch and line coverage
|
|
76
|
+
- Assess risk of uncovered code
|
|
77
|
+
- Provide actionable recommendations
|
|
78
|
+
|
|
79
|
+
Your analysis focuses on:
|
|
80
|
+
- High-risk uncovered code (error handling, security)
|
|
81
|
+
- Business-critical paths
|
|
82
|
+
- Complex logic with low coverage
|
|
83
|
+
- Recently changed code
|
|
84
|
+
- Public APIs and interfaces
|
|
85
|
+
|
|
86
|
+
Format your analysis as structured JSON with clear priorities and recommendations.
|
|
87
|
+
`.trim();
|
|
88
|
+
/**
|
|
89
|
+
* System prompt for Security Scanner Agent
|
|
90
|
+
*/
|
|
91
|
+
const SECURITY_SCANNER_SYSTEM_PROMPT = `
|
|
92
|
+
You are an expert Security Scanner Agent specialized in identifying security vulnerabilities.
|
|
93
|
+
|
|
94
|
+
Your capabilities include:
|
|
95
|
+
1. Scanning code for OWASP Top 10 vulnerabilities
|
|
96
|
+
2. Detecting SQL injection, XSS, CSRF risks
|
|
97
|
+
3. Identifying authentication and authorization flaws
|
|
98
|
+
4. Finding hardcoded secrets and sensitive data exposure
|
|
99
|
+
5. Analyzing dependencies for known vulnerabilities
|
|
100
|
+
|
|
101
|
+
When scanning:
|
|
102
|
+
- Use static analysis patterns
|
|
103
|
+
- Check for common vulnerability patterns
|
|
104
|
+
- Validate input sanitization
|
|
105
|
+
- Review authentication mechanisms
|
|
106
|
+
- Assess cryptographic usage
|
|
107
|
+
- Identify sensitive data exposure
|
|
108
|
+
|
|
109
|
+
Your scan focuses on:
|
|
110
|
+
- Injection vulnerabilities (SQL, NoSQL, OS command)
|
|
111
|
+
- Broken authentication and session management
|
|
112
|
+
- Sensitive data exposure
|
|
113
|
+
- XML external entities (XXE)
|
|
114
|
+
- Broken access control
|
|
115
|
+
- Security misconfigurations
|
|
116
|
+
- Cross-site scripting (XSS)
|
|
117
|
+
- Insecure deserialization
|
|
118
|
+
- Using components with known vulnerabilities
|
|
119
|
+
- Insufficient logging and monitoring
|
|
120
|
+
|
|
121
|
+
Format your findings as structured JSON with severity levels, descriptions, and remediation steps.
|
|
122
|
+
`.trim();
|
|
123
|
+
/**
|
|
124
|
+
* Example: Test Generator with Prompt Caching
|
|
125
|
+
*
|
|
126
|
+
* Demonstrates caching system prompt and project context for test generation.
|
|
127
|
+
*/
|
|
128
|
+
async function generateTestsWithCache(params) {
|
|
129
|
+
const cacheManager = new prompt_cache_1.PromptCacheManager(params.apiKey);
|
|
130
|
+
// System prompt is large and stable - perfect for caching
|
|
131
|
+
const systemPrompt = TEST_GENERATOR_SYSTEM_PROMPT;
|
|
132
|
+
// Project context changes per project but stable within project
|
|
133
|
+
const projectContext = {
|
|
134
|
+
structure: params.projectStructure,
|
|
135
|
+
guidelines: params.guidelines,
|
|
136
|
+
framework: params.framework,
|
|
137
|
+
};
|
|
138
|
+
// Make cached request
|
|
139
|
+
const response = await cacheManager.createWithCache({
|
|
140
|
+
model: 'claude-sonnet-4',
|
|
141
|
+
systemPrompts: [
|
|
142
|
+
{
|
|
143
|
+
text: systemPrompt,
|
|
144
|
+
priority: 'high', // System prompt is critical and large
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
projectContext: [
|
|
148
|
+
{
|
|
149
|
+
text: JSON.stringify(projectContext.structure, null, 2),
|
|
150
|
+
priority: 'medium',
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
text: projectContext.guidelines,
|
|
154
|
+
priority: 'medium',
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
messages: [
|
|
158
|
+
{
|
|
159
|
+
role: 'user',
|
|
160
|
+
content: `Generate ${params.framework} tests for the following code:\n\nFile: ${params.sourceFile}\n\n${params.sourceCode}`,
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
maxTokens: 4096,
|
|
164
|
+
temperature: 0.3, // Lower temperature for more deterministic tests
|
|
165
|
+
});
|
|
166
|
+
// Extract test code from response
|
|
167
|
+
const testCode = response.content[0].type === 'text' ? response.content[0].text : '';
|
|
168
|
+
// Get cache statistics
|
|
169
|
+
const stats = cacheManager.getStats();
|
|
170
|
+
return {
|
|
171
|
+
testCode,
|
|
172
|
+
cacheStats: {
|
|
173
|
+
hitRate: `${(stats.hitRate * 100).toFixed(1)}%`,
|
|
174
|
+
costSavings: `$${stats.costSavings.toFixed(4)}`,
|
|
175
|
+
hits: stats.hits,
|
|
176
|
+
misses: stats.misses,
|
|
177
|
+
tokensRead: stats.tokensRead,
|
|
178
|
+
tokensWritten: stats.tokensWritten,
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Example: Coverage Analyzer with Prompt Caching
|
|
184
|
+
*
|
|
185
|
+
* Demonstrates caching for coverage analysis with large coverage reports.
|
|
186
|
+
*/
|
|
187
|
+
async function analyzeCoverageWithCache(params) {
|
|
188
|
+
const cacheManager = new prompt_cache_1.PromptCacheManager(params.apiKey);
|
|
189
|
+
// System prompt defines coverage analysis behavior
|
|
190
|
+
const systemPrompt = COVERAGE_ANALYZER_SYSTEM_PROMPT;
|
|
191
|
+
// Project metadata is stable within project
|
|
192
|
+
const projectContext = JSON.stringify(params.projectMetadata, null, 2);
|
|
193
|
+
// Make cached request
|
|
194
|
+
const response = await cacheManager.createWithCache({
|
|
195
|
+
model: 'claude-sonnet-4',
|
|
196
|
+
systemPrompts: [
|
|
197
|
+
{
|
|
198
|
+
text: systemPrompt,
|
|
199
|
+
priority: 'high',
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
projectContext: [
|
|
203
|
+
{
|
|
204
|
+
text: projectContext,
|
|
205
|
+
priority: 'medium',
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
messages: [
|
|
209
|
+
{
|
|
210
|
+
role: 'user',
|
|
211
|
+
content: `Analyze the following coverage data and identify top gaps:\n\n${JSON.stringify(params.coverageData, null, 2)}`,
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
maxTokens: 4096,
|
|
215
|
+
temperature: 0.2, // Very low temperature for consistent analysis
|
|
216
|
+
});
|
|
217
|
+
// Parse analysis from response
|
|
218
|
+
const analysisText = response.content[0].type === 'text' ? response.content[0].text : '';
|
|
219
|
+
let analysis;
|
|
220
|
+
try {
|
|
221
|
+
analysis = JSON.parse(analysisText);
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
analysis = { raw: analysisText };
|
|
225
|
+
}
|
|
226
|
+
// Get cache statistics
|
|
227
|
+
const stats = cacheManager.getStats();
|
|
228
|
+
return {
|
|
229
|
+
analysis,
|
|
230
|
+
cacheStats: {
|
|
231
|
+
hitRate: `${(stats.hitRate * 100).toFixed(1)}%`,
|
|
232
|
+
costSavings: `$${stats.costSavings.toFixed(4)}`,
|
|
233
|
+
hits: stats.hits,
|
|
234
|
+
misses: stats.misses,
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Example: Security Scanner with Prompt Caching
|
|
240
|
+
*
|
|
241
|
+
* Demonstrates caching for security scans with vulnerability patterns.
|
|
242
|
+
*/
|
|
243
|
+
async function scanSecurityWithCache(params) {
|
|
244
|
+
const cacheManager = new prompt_cache_1.PromptCacheManager(params.apiKey);
|
|
245
|
+
// System prompt includes OWASP patterns and rules
|
|
246
|
+
const systemPrompt = SECURITY_SCANNER_SYSTEM_PROMPT;
|
|
247
|
+
// Security rules are project-specific but stable
|
|
248
|
+
const rulesContext = JSON.stringify({
|
|
249
|
+
rules: params.securityRules,
|
|
250
|
+
standards: ['OWASP Top 10', 'CWE', 'SANS 25'],
|
|
251
|
+
}, null, 2);
|
|
252
|
+
// Make cached request
|
|
253
|
+
const response = await cacheManager.createWithCache({
|
|
254
|
+
model: 'claude-sonnet-4',
|
|
255
|
+
systemPrompts: [
|
|
256
|
+
{
|
|
257
|
+
text: systemPrompt,
|
|
258
|
+
priority: 'high',
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
projectContext: [
|
|
262
|
+
{
|
|
263
|
+
text: rulesContext,
|
|
264
|
+
priority: 'medium',
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
messages: [
|
|
268
|
+
{
|
|
269
|
+
role: 'user',
|
|
270
|
+
content: `Scan the following code for security vulnerabilities:\n\nFile: ${params.fileName}\n\n${params.sourceCode}`,
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
maxTokens: 4096,
|
|
274
|
+
temperature: 0.1, // Lowest temperature for consistent security analysis
|
|
275
|
+
});
|
|
276
|
+
// Parse findings from response
|
|
277
|
+
const findingsText = response.content[0].type === 'text' ? response.content[0].text : '';
|
|
278
|
+
let findings;
|
|
279
|
+
try {
|
|
280
|
+
findings = JSON.parse(findingsText);
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
findings = { raw: findingsText };
|
|
284
|
+
}
|
|
285
|
+
// Get cache statistics
|
|
286
|
+
const stats = cacheManager.getStats();
|
|
287
|
+
return {
|
|
288
|
+
findings,
|
|
289
|
+
cacheStats: {
|
|
290
|
+
hitRate: `${(stats.hitRate * 100).toFixed(1)}%`,
|
|
291
|
+
costSavings: `$${stats.costSavings.toFixed(4)}`,
|
|
292
|
+
hits: stats.hits,
|
|
293
|
+
misses: stats.misses,
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Example: Batch Test Generation with Cache Monitoring
|
|
299
|
+
*
|
|
300
|
+
* Demonstrates how cache performance improves over multiple calls.
|
|
301
|
+
*/
|
|
302
|
+
async function batchGenerateTestsWithCacheMonitoring(params) {
|
|
303
|
+
const cacheManager = new prompt_cache_1.PromptCacheManager(params.apiKey);
|
|
304
|
+
const systemPrompt = TEST_GENERATOR_SYSTEM_PROMPT;
|
|
305
|
+
const projectContextText = JSON.stringify(params.projectContext, null, 2);
|
|
306
|
+
const results = [];
|
|
307
|
+
// Process files sequentially to demonstrate cache warming
|
|
308
|
+
for (const file of params.files) {
|
|
309
|
+
const response = await cacheManager.createWithCache({
|
|
310
|
+
model: 'claude-sonnet-4',
|
|
311
|
+
systemPrompts: [
|
|
312
|
+
{
|
|
313
|
+
text: systemPrompt,
|
|
314
|
+
priority: 'high',
|
|
315
|
+
},
|
|
316
|
+
],
|
|
317
|
+
projectContext: [
|
|
318
|
+
{
|
|
319
|
+
text: projectContextText,
|
|
320
|
+
priority: 'medium',
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
messages: [
|
|
324
|
+
{
|
|
325
|
+
role: 'user',
|
|
326
|
+
content: `Generate ${params.framework} tests for:\n\n${file.path}\n\n${file.content}`,
|
|
327
|
+
},
|
|
328
|
+
],
|
|
329
|
+
});
|
|
330
|
+
const testCode = response.content[0].type === 'text' ? response.content[0].text : '';
|
|
331
|
+
results.push({ file: file.path, testCode });
|
|
332
|
+
// Log progress
|
|
333
|
+
const stats = cacheManager.getStats();
|
|
334
|
+
console.log(`Processed ${file.path} - Hit rate: ${(stats.hitRate * 100).toFixed(1)}%`);
|
|
335
|
+
}
|
|
336
|
+
// Final statistics
|
|
337
|
+
const finalStats = cacheManager.getStats();
|
|
338
|
+
// Calculate break-even analysis
|
|
339
|
+
const estimatedCacheTokens = 18000; // Approximate system + context tokens
|
|
340
|
+
const breakEven = prompt_cache_1.PromptCacheManager.calculateBreakEven(estimatedCacheTokens);
|
|
341
|
+
return {
|
|
342
|
+
results,
|
|
343
|
+
finalStats: {
|
|
344
|
+
hitRate: `${(finalStats.hitRate * 100).toFixed(1)}%`,
|
|
345
|
+
costSavings: `$${finalStats.costSavings.toFixed(4)}`,
|
|
346
|
+
totalHits: finalStats.hits,
|
|
347
|
+
totalMisses: finalStats.misses,
|
|
348
|
+
breakEvenAnalysis: {
|
|
349
|
+
hitsNeeded: breakEven.hitsToBreakEven,
|
|
350
|
+
actualHits: finalStats.hits,
|
|
351
|
+
metBreakEven: finalStats.hits >= breakEven.hitsToBreakEven,
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Example: Periodic Cache Maintenance
|
|
358
|
+
*
|
|
359
|
+
* Demonstrates how to set up periodic cache pruning in a long-running service.
|
|
360
|
+
*/
|
|
361
|
+
function setupCacheMaintenance(cacheManager) {
|
|
362
|
+
// Prune cache every 5 minutes
|
|
363
|
+
const intervalId = setInterval(() => {
|
|
364
|
+
const pruned = cacheManager.pruneCache();
|
|
365
|
+
if (pruned > 0) {
|
|
366
|
+
console.log(`[Cache Maintenance] Pruned ${pruned} expired entries`);
|
|
367
|
+
}
|
|
368
|
+
// Log statistics
|
|
369
|
+
const stats = cacheManager.getStats();
|
|
370
|
+
console.log(`[Cache Maintenance] Hit rate: ${(stats.hitRate * 100).toFixed(1)}%, Savings: $${stats.costSavings.toFixed(4)}`);
|
|
371
|
+
}, 5 * 60 * 1000);
|
|
372
|
+
return {
|
|
373
|
+
stop: () => {
|
|
374
|
+
clearInterval(intervalId);
|
|
375
|
+
console.log('[Cache Maintenance] Stopped');
|
|
376
|
+
},
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Example: Daily Statistics Reset
|
|
381
|
+
*
|
|
382
|
+
* Demonstrates how to reset statistics at the start of each day for daily reporting.
|
|
383
|
+
*/
|
|
384
|
+
function setupDailyStatsReset(cacheManager) {
|
|
385
|
+
// Calculate time until next midnight
|
|
386
|
+
const now = new Date();
|
|
387
|
+
const tomorrow = new Date(now);
|
|
388
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
389
|
+
tomorrow.setHours(0, 0, 0, 0);
|
|
390
|
+
const msUntilMidnight = tomorrow.getTime() - now.getTime();
|
|
391
|
+
// Reset at midnight
|
|
392
|
+
const timeoutId = setTimeout(() => {
|
|
393
|
+
const stats = cacheManager.getStats();
|
|
394
|
+
console.log(`[Daily Stats] Yesterday: ${(stats.hitRate * 100).toFixed(1)}% hit rate, $${stats.costSavings.toFixed(4)} savings`);
|
|
395
|
+
cacheManager.resetStats();
|
|
396
|
+
console.log('[Daily Stats] Reset for new day');
|
|
397
|
+
// Set up daily interval
|
|
398
|
+
const intervalId = setInterval(() => {
|
|
399
|
+
const dailyStats = cacheManager.getStats();
|
|
400
|
+
console.log(`[Daily Stats] ${(dailyStats.hitRate * 100).toFixed(1)}% hit rate, $${dailyStats.costSavings.toFixed(4)} savings`);
|
|
401
|
+
cacheManager.resetStats();
|
|
402
|
+
}, 24 * 60 * 60 * 1000);
|
|
403
|
+
// Store interval ID for cleanup
|
|
404
|
+
setupDailyStatsReset.intervalId = intervalId;
|
|
405
|
+
}, msUntilMidnight);
|
|
406
|
+
return {
|
|
407
|
+
stop: () => {
|
|
408
|
+
clearTimeout(timeoutId);
|
|
409
|
+
if (setupDailyStatsReset.intervalId) {
|
|
410
|
+
clearInterval(setupDailyStatsReset.intervalId);
|
|
411
|
+
}
|
|
412
|
+
console.log('[Daily Stats] Stopped');
|
|
413
|
+
},
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
//# sourceMappingURL=prompt-cache-examples.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-cache-examples.js","sourceRoot":"","sources":["../../src/utils/prompt-cache-examples.ts"],"names":[],"mappings":"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"}
|