@juspay/yama 1.5.1 → 2.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 (67) hide show
  1. package/.mcp-config.example.json +26 -0
  2. package/CHANGELOG.md +40 -0
  3. package/README.md +311 -685
  4. package/dist/cli/v2.cli.d.ts +13 -0
  5. package/dist/cli/v2.cli.js +290 -0
  6. package/dist/index.d.ts +12 -13
  7. package/dist/index.js +18 -19
  8. package/dist/v2/config/ConfigLoader.d.ts +50 -0
  9. package/dist/v2/config/ConfigLoader.js +205 -0
  10. package/dist/v2/config/DefaultConfig.d.ts +9 -0
  11. package/dist/v2/config/DefaultConfig.js +191 -0
  12. package/dist/v2/core/MCPServerManager.d.ts +22 -0
  13. package/dist/v2/core/MCPServerManager.js +92 -0
  14. package/dist/v2/core/SessionManager.d.ts +72 -0
  15. package/dist/v2/core/SessionManager.js +200 -0
  16. package/dist/v2/core/YamaV2Orchestrator.d.ts +112 -0
  17. package/dist/v2/core/YamaV2Orchestrator.js +549 -0
  18. package/dist/v2/prompts/EnhancementSystemPrompt.d.ts +8 -0
  19. package/dist/v2/prompts/EnhancementSystemPrompt.js +216 -0
  20. package/dist/v2/prompts/PromptBuilder.d.ts +38 -0
  21. package/dist/v2/prompts/PromptBuilder.js +228 -0
  22. package/dist/v2/prompts/ReviewSystemPrompt.d.ts +8 -0
  23. package/dist/v2/prompts/ReviewSystemPrompt.js +270 -0
  24. package/dist/v2/types/config.types.d.ts +120 -0
  25. package/dist/v2/types/config.types.js +5 -0
  26. package/dist/v2/types/mcp.types.d.ts +191 -0
  27. package/dist/v2/types/mcp.types.js +6 -0
  28. package/dist/v2/types/v2.types.d.ts +182 -0
  29. package/dist/v2/types/v2.types.js +42 -0
  30. package/dist/v2/utils/ObservabilityConfig.d.ts +22 -0
  31. package/dist/v2/utils/ObservabilityConfig.js +48 -0
  32. package/package.json +11 -9
  33. package/yama.config.example.yaml +214 -193
  34. package/dist/cli/index.d.ts +0 -12
  35. package/dist/cli/index.js +0 -538
  36. package/dist/core/ContextGatherer.d.ts +0 -110
  37. package/dist/core/ContextGatherer.js +0 -470
  38. package/dist/core/Guardian.d.ts +0 -81
  39. package/dist/core/Guardian.js +0 -474
  40. package/dist/core/providers/BitbucketProvider.d.ts +0 -105
  41. package/dist/core/providers/BitbucketProvider.js +0 -489
  42. package/dist/features/CodeReviewer.d.ts +0 -173
  43. package/dist/features/CodeReviewer.js +0 -1707
  44. package/dist/features/DescriptionEnhancer.d.ts +0 -64
  45. package/dist/features/DescriptionEnhancer.js +0 -445
  46. package/dist/features/MultiInstanceProcessor.d.ts +0 -74
  47. package/dist/features/MultiInstanceProcessor.js +0 -360
  48. package/dist/types/index.d.ts +0 -624
  49. package/dist/types/index.js +0 -104
  50. package/dist/utils/Cache.d.ts +0 -103
  51. package/dist/utils/Cache.js +0 -444
  52. package/dist/utils/ConfigManager.d.ts +0 -88
  53. package/dist/utils/ConfigManager.js +0 -603
  54. package/dist/utils/ContentSimilarityService.d.ts +0 -74
  55. package/dist/utils/ContentSimilarityService.js +0 -215
  56. package/dist/utils/ExactDuplicateRemover.d.ts +0 -77
  57. package/dist/utils/ExactDuplicateRemover.js +0 -361
  58. package/dist/utils/Logger.d.ts +0 -31
  59. package/dist/utils/Logger.js +0 -214
  60. package/dist/utils/MemoryBankManager.d.ts +0 -73
  61. package/dist/utils/MemoryBankManager.js +0 -310
  62. package/dist/utils/ParallelProcessing.d.ts +0 -140
  63. package/dist/utils/ParallelProcessing.js +0 -333
  64. package/dist/utils/ProviderLimits.d.ts +0 -58
  65. package/dist/utils/ProviderLimits.js +0 -143
  66. package/dist/utils/RetryManager.d.ts +0 -78
  67. package/dist/utils/RetryManager.js +0 -205
@@ -1,205 +0,0 @@
1
- /**
2
- * Retry Manager for Yama
3
- * Provides intelligent retry logic with exponential backoff for handling transient failures
4
- */
5
- import { logger } from "./Logger.js";
6
- export class RetryManager {
7
- static DEFAULT_OPTIONS = {
8
- maxAttempts: 3,
9
- baseDelayMs: 1000,
10
- maxDelayMs: 10000,
11
- backoffMultiplier: 2.0,
12
- jitterMs: 100,
13
- retryableErrors: [
14
- "provider_error",
15
- "network",
16
- "timeout",
17
- "connection",
18
- "econnreset",
19
- "etimedout",
20
- "enotfound",
21
- "econnrefused",
22
- "socket hang up",
23
- "request timeout",
24
- "service unavailable",
25
- "bad gateway",
26
- "gateway timeout",
27
- "temporary failure",
28
- "rate limit",
29
- ],
30
- };
31
- /**
32
- * Execute an operation with retry logic
33
- */
34
- static async withRetry(operation, context, options = {}) {
35
- const opts = { ...RetryManager.DEFAULT_OPTIONS, ...options };
36
- const startTime = Date.now();
37
- let lastError;
38
- for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {
39
- try {
40
- const result = await operation();
41
- if (attempt > 1) {
42
- const elapsed = Date.now() - startTime;
43
- logger.info(`${context} succeeded on attempt ${attempt} after ${elapsed}ms`);
44
- }
45
- return result;
46
- }
47
- catch (error) {
48
- lastError = error;
49
- const isLastAttempt = attempt === opts.maxAttempts;
50
- const isRetryable = RetryManager.isRetryableError(lastError, opts.retryableErrors);
51
- const elapsed = Date.now() - startTime;
52
- const retryContext = {
53
- operation: context,
54
- attempt,
55
- maxAttempts: opts.maxAttempts,
56
- lastError,
57
- totalElapsed: elapsed,
58
- };
59
- if (isLastAttempt || !isRetryable) {
60
- if (isLastAttempt) {
61
- logger.error(`${context} failed after ${opts.maxAttempts} attempts (${elapsed}ms total):`, lastError);
62
- }
63
- else {
64
- logger.error(`${context} failed with non-retryable error:`, lastError);
65
- }
66
- throw lastError;
67
- }
68
- const delay = RetryManager.calculateDelay(attempt, opts);
69
- logger.warn(`${context} failed (attempt ${attempt}/${opts.maxAttempts}), retrying in ${delay}ms:`, lastError.message);
70
- await RetryManager.sleep(delay);
71
- }
72
- }
73
- // This should never be reached, but TypeScript requires it
74
- throw (lastError ||
75
- new Error(`${context} failed after ${opts.maxAttempts} attempts`));
76
- }
77
- /**
78
- * Check if an error is retryable based on error patterns
79
- */
80
- static isRetryableError(error, retryablePatterns) {
81
- if (!error) {
82
- return false;
83
- }
84
- const errorMessage = error.message?.toLowerCase() || "";
85
- const errorCode = error.code?.toLowerCase() || "";
86
- const errorName = error.name?.toLowerCase() || "";
87
- // Check if any retryable pattern matches the error
88
- return retryablePatterns.some((pattern) => {
89
- const lowerPattern = pattern.toLowerCase();
90
- return (errorMessage.includes(lowerPattern) ||
91
- errorCode.includes(lowerPattern) ||
92
- errorName.includes(lowerPattern));
93
- });
94
- }
95
- /**
96
- * Calculate delay with exponential backoff and jitter
97
- */
98
- static calculateDelay(attempt, options) {
99
- // Exponential backoff: baseDelay * (multiplier ^ (attempt - 1))
100
- const exponentialDelay = options.baseDelayMs * Math.pow(options.backoffMultiplier, attempt - 1);
101
- // Apply maximum delay cap
102
- const cappedDelay = Math.min(exponentialDelay, options.maxDelayMs);
103
- // Add jitter to prevent thundering herd
104
- const jitter = Math.random() * options.jitterMs;
105
- return Math.floor(cappedDelay + jitter);
106
- }
107
- /**
108
- * Sleep for specified milliseconds
109
- */
110
- static sleep(ms) {
111
- return new Promise((resolve) => setTimeout(resolve, ms));
112
- }
113
- /**
114
- * Create a retry wrapper function for a specific operation
115
- */
116
- static createRetryWrapper(fn, context, options = {}) {
117
- return async (...args) => {
118
- return RetryManager.withRetry(() => fn(...args), context, options);
119
- };
120
- }
121
- /**
122
- * Batch retry operations with individual retry logic
123
- */
124
- static async batchWithRetry(operations, options = {}) {
125
- const { continueOnError = true, ...retryOptions } = options;
126
- const results = [];
127
- for (const { fn, context } of operations) {
128
- try {
129
- const data = await RetryManager.withRetry(fn, context, retryOptions);
130
- results.push({ success: true, data, context });
131
- }
132
- catch (error) {
133
- const err = error;
134
- results.push({ success: false, error: err, context });
135
- if (!continueOnError) {
136
- throw error;
137
- }
138
- }
139
- }
140
- return results;
141
- }
142
- /**
143
- * Get retry statistics for monitoring
144
- */
145
- static getRetryStats(results) {
146
- const total = results.length;
147
- const successful = results.filter((r) => r.success).length;
148
- const failed = total - successful;
149
- const successRate = total > 0 ? successful / total : 0;
150
- const failuresByContext = {};
151
- results
152
- .filter((r) => !r.success)
153
- .forEach((r) => {
154
- failuresByContext[r.context] = (failuresByContext[r.context] || 0) + 1;
155
- });
156
- return {
157
- total,
158
- successful,
159
- failed,
160
- successRate,
161
- failuresByContext,
162
- };
163
- }
164
- /**
165
- * Create a circuit breaker pattern (simple implementation)
166
- */
167
- static createCircuitBreaker(fn, context, options = {}) {
168
- const { failureThreshold = 5, recoveryTimeoutMs = 30000, retryOptions = {}, } = options;
169
- let failureCount = 0;
170
- let lastFailureTime = 0;
171
- let state = "CLOSED";
172
- return async (...args) => {
173
- const now = Date.now();
174
- // Check if we should attempt recovery
175
- if (state === "OPEN" && now - lastFailureTime > recoveryTimeoutMs) {
176
- state = "HALF_OPEN";
177
- logger.debug(`Circuit breaker for ${context} entering HALF_OPEN state`);
178
- }
179
- // Reject immediately if circuit is open
180
- if (state === "OPEN") {
181
- throw new Error(`Circuit breaker OPEN for ${context} (${failureCount} failures)`);
182
- }
183
- try {
184
- const result = await RetryManager.withRetry(() => fn(...args), context, retryOptions);
185
- // Success - reset circuit breaker
186
- if (state === "HALF_OPEN") {
187
- state = "CLOSED";
188
- failureCount = 0;
189
- logger.info(`Circuit breaker for ${context} recovered to CLOSED state`);
190
- }
191
- return result;
192
- }
193
- catch (error) {
194
- failureCount++;
195
- lastFailureTime = now;
196
- if (failureCount >= failureThreshold) {
197
- state = "OPEN";
198
- logger.error(`Circuit breaker OPEN for ${context} after ${failureCount} failures`);
199
- }
200
- throw error;
201
- }
202
- };
203
- }
204
- }
205
- //# sourceMappingURL=RetryManager.js.map