@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.
- package/.mcp-config.example.json +26 -0
- package/CHANGELOG.md +40 -0
- package/README.md +311 -685
- package/dist/cli/v2.cli.d.ts +13 -0
- package/dist/cli/v2.cli.js +290 -0
- package/dist/index.d.ts +12 -13
- package/dist/index.js +18 -19
- package/dist/v2/config/ConfigLoader.d.ts +50 -0
- package/dist/v2/config/ConfigLoader.js +205 -0
- package/dist/v2/config/DefaultConfig.d.ts +9 -0
- package/dist/v2/config/DefaultConfig.js +191 -0
- package/dist/v2/core/MCPServerManager.d.ts +22 -0
- package/dist/v2/core/MCPServerManager.js +92 -0
- package/dist/v2/core/SessionManager.d.ts +72 -0
- package/dist/v2/core/SessionManager.js +200 -0
- package/dist/v2/core/YamaV2Orchestrator.d.ts +112 -0
- package/dist/v2/core/YamaV2Orchestrator.js +549 -0
- package/dist/v2/prompts/EnhancementSystemPrompt.d.ts +8 -0
- package/dist/v2/prompts/EnhancementSystemPrompt.js +216 -0
- package/dist/v2/prompts/PromptBuilder.d.ts +38 -0
- package/dist/v2/prompts/PromptBuilder.js +228 -0
- package/dist/v2/prompts/ReviewSystemPrompt.d.ts +8 -0
- package/dist/v2/prompts/ReviewSystemPrompt.js +270 -0
- package/dist/v2/types/config.types.d.ts +120 -0
- package/dist/v2/types/config.types.js +5 -0
- package/dist/v2/types/mcp.types.d.ts +191 -0
- package/dist/v2/types/mcp.types.js +6 -0
- package/dist/v2/types/v2.types.d.ts +182 -0
- package/dist/v2/types/v2.types.js +42 -0
- package/dist/v2/utils/ObservabilityConfig.d.ts +22 -0
- package/dist/v2/utils/ObservabilityConfig.js +48 -0
- package/package.json +11 -9
- package/yama.config.example.yaml +214 -193
- package/dist/cli/index.d.ts +0 -12
- package/dist/cli/index.js +0 -538
- package/dist/core/ContextGatherer.d.ts +0 -110
- package/dist/core/ContextGatherer.js +0 -470
- package/dist/core/Guardian.d.ts +0 -81
- package/dist/core/Guardian.js +0 -474
- package/dist/core/providers/BitbucketProvider.d.ts +0 -105
- package/dist/core/providers/BitbucketProvider.js +0 -489
- package/dist/features/CodeReviewer.d.ts +0 -173
- package/dist/features/CodeReviewer.js +0 -1707
- package/dist/features/DescriptionEnhancer.d.ts +0 -64
- package/dist/features/DescriptionEnhancer.js +0 -445
- package/dist/features/MultiInstanceProcessor.d.ts +0 -74
- package/dist/features/MultiInstanceProcessor.js +0 -360
- package/dist/types/index.d.ts +0 -624
- package/dist/types/index.js +0 -104
- package/dist/utils/Cache.d.ts +0 -103
- package/dist/utils/Cache.js +0 -444
- package/dist/utils/ConfigManager.d.ts +0 -88
- package/dist/utils/ConfigManager.js +0 -603
- package/dist/utils/ContentSimilarityService.d.ts +0 -74
- package/dist/utils/ContentSimilarityService.js +0 -215
- package/dist/utils/ExactDuplicateRemover.d.ts +0 -77
- package/dist/utils/ExactDuplicateRemover.js +0 -361
- package/dist/utils/Logger.d.ts +0 -31
- package/dist/utils/Logger.js +0 -214
- package/dist/utils/MemoryBankManager.d.ts +0 -73
- package/dist/utils/MemoryBankManager.js +0 -310
- package/dist/utils/ParallelProcessing.d.ts +0 -140
- package/dist/utils/ParallelProcessing.js +0 -333
- package/dist/utils/ProviderLimits.d.ts +0 -58
- package/dist/utils/ProviderLimits.js +0 -143
- package/dist/utils/RetryManager.d.ts +0 -78
- package/dist/utils/RetryManager.js +0 -205
|
@@ -1,333 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parallel Processing Utilities for Batch Processing
|
|
3
|
-
* Provides concurrency control and resource management for parallel batch execution
|
|
4
|
-
*/
|
|
5
|
-
import { logger } from "./Logger.js";
|
|
6
|
-
/**
|
|
7
|
-
* Semaphore for controlling concurrent access to resources
|
|
8
|
-
* Limits the number of concurrent operations that can run simultaneously
|
|
9
|
-
*/
|
|
10
|
-
export class Semaphore {
|
|
11
|
-
permits;
|
|
12
|
-
waiting = [];
|
|
13
|
-
constructor(permits) {
|
|
14
|
-
if (permits <= 0) {
|
|
15
|
-
throw new Error("Semaphore permits must be greater than 0");
|
|
16
|
-
}
|
|
17
|
-
this.permits = permits;
|
|
18
|
-
logger.debug(`Semaphore created with ${permits} permits`);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Acquire a permit from the semaphore
|
|
22
|
-
* If no permits are available, the caller will wait until one becomes available
|
|
23
|
-
*/
|
|
24
|
-
async acquire() {
|
|
25
|
-
if (this.permits > 0) {
|
|
26
|
-
this.permits--;
|
|
27
|
-
logger.debug(`Semaphore permit acquired, ${this.permits} remaining`);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
logger.debug(`Semaphore permit requested, waiting in queue (${this.waiting.length} waiting)`);
|
|
31
|
-
return new Promise((resolve) => {
|
|
32
|
-
this.waiting.push(resolve);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Release a permit back to the semaphore
|
|
37
|
-
* This will allow waiting operations to proceed
|
|
38
|
-
*/
|
|
39
|
-
release() {
|
|
40
|
-
this.permits++;
|
|
41
|
-
logger.debug(`Semaphore permit released, ${this.permits} available`);
|
|
42
|
-
if (this.waiting.length > 0) {
|
|
43
|
-
const resolve = this.waiting.shift();
|
|
44
|
-
this.permits--;
|
|
45
|
-
logger.debug(`Semaphore permit granted to waiting operation, ${this.permits} remaining`);
|
|
46
|
-
resolve();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Get the number of available permits
|
|
51
|
-
*/
|
|
52
|
-
getAvailablePermits() {
|
|
53
|
-
return this.permits;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Get the number of operations waiting for permits
|
|
57
|
-
*/
|
|
58
|
-
getWaitingCount() {
|
|
59
|
-
return this.waiting.length;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Get semaphore status for debugging
|
|
63
|
-
*/
|
|
64
|
-
getStatus() {
|
|
65
|
-
return {
|
|
66
|
-
available: this.permits,
|
|
67
|
-
waiting: this.waiting.length,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Token Budget Manager for controlling AI token usage across parallel batches
|
|
73
|
-
* Ensures that the total token usage doesn't exceed the configured limits
|
|
74
|
-
*/
|
|
75
|
-
export class TokenBudgetManager {
|
|
76
|
-
totalBudget;
|
|
77
|
-
usedTokens = 0;
|
|
78
|
-
batchAllocations = new Map();
|
|
79
|
-
reservedTokens = 0; // Tokens allocated but not yet used
|
|
80
|
-
// NEW: Pre-allocation mode tracking
|
|
81
|
-
preAllocationMode = false;
|
|
82
|
-
preAllocatedBatches = new Set();
|
|
83
|
-
batchStates = new Map();
|
|
84
|
-
constructor(totalBudget) {
|
|
85
|
-
if (totalBudget <= 0) {
|
|
86
|
-
throw new Error("Token budget must be greater than 0");
|
|
87
|
-
}
|
|
88
|
-
// Floor the budget to ensure integer arithmetic and avoid floating-point precision issues.
|
|
89
|
-
// The fractional part is discarded, so the budget is always rounded down.
|
|
90
|
-
this.totalBudget = Math.floor(totalBudget);
|
|
91
|
-
logger.debug(`TokenBudgetManager created with budget of ${this.totalBudget} tokens (original: ${totalBudget})`);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Allocate tokens for a specific batch
|
|
95
|
-
* Returns true if allocation was successful, false if insufficient budget
|
|
96
|
-
*/
|
|
97
|
-
allocateForBatch(batchIndex, estimatedTokens) {
|
|
98
|
-
if (estimatedTokens <= 0) {
|
|
99
|
-
logger.warn(`Invalid token estimate for batch ${batchIndex}: ${estimatedTokens}`);
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
// NEW: Handle pre-allocation mode
|
|
103
|
-
if (this.preAllocationMode && this.preAllocatedBatches.has(batchIndex)) {
|
|
104
|
-
// Check if batch is already being processed
|
|
105
|
-
const currentState = this.batchStates.get(batchIndex);
|
|
106
|
-
if (currentState === "processing") {
|
|
107
|
-
logger.warn(`Batch ${batchIndex} is already being processed`);
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
if (currentState !== "pending") {
|
|
111
|
-
logger.warn(`Batch ${batchIndex} is not in pending state (current: ${currentState})`);
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
// In pre-allocation mode, just mark batch as processing and return success
|
|
115
|
-
this.batchStates.set(batchIndex, "processing");
|
|
116
|
-
logger.debug(`Batch ${batchIndex} using pre-allocated tokens (${this.batchAllocations.get(batchIndex)} tokens)`);
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
// Check if we already have an allocation for this batch (non-pre-allocation mode)
|
|
120
|
-
if (this.batchAllocations.has(batchIndex)) {
|
|
121
|
-
// Check if batch is already being processed
|
|
122
|
-
const currentState = this.batchStates.get(batchIndex);
|
|
123
|
-
if (currentState === "processing") {
|
|
124
|
-
logger.warn(`Batch ${batchIndex} is already being processed`);
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
logger.warn(`Batch ${batchIndex} already has token allocation`);
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
// Check if we have enough budget
|
|
131
|
-
const totalAllocated = this.usedTokens + this.reservedTokens + estimatedTokens;
|
|
132
|
-
if (totalAllocated > this.totalBudget) {
|
|
133
|
-
logger.debug(`Insufficient token budget for batch ${batchIndex}: ` +
|
|
134
|
-
`need ${estimatedTokens}, available ${this.getAvailableBudget()}`);
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
// Allocate the tokens
|
|
138
|
-
this.reservedTokens += estimatedTokens;
|
|
139
|
-
this.batchAllocations.set(batchIndex, estimatedTokens);
|
|
140
|
-
this.batchStates.set(batchIndex, "processing");
|
|
141
|
-
logger.debug(`Allocated ${estimatedTokens} tokens for batch ${batchIndex} ` +
|
|
142
|
-
`(${this.getAvailableBudget()} remaining)`);
|
|
143
|
-
return true;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Release tokens allocated to a batch
|
|
147
|
-
* This should be called when a batch completes (successfully or with error)
|
|
148
|
-
*/
|
|
149
|
-
releaseBatch(batchIndex) {
|
|
150
|
-
const allocated = this.batchAllocations.get(batchIndex);
|
|
151
|
-
if (!allocated) {
|
|
152
|
-
logger.warn(`No token allocation found for batch ${batchIndex}`);
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
// Update batch state to completed only if not already failed
|
|
156
|
-
const currentState = this.batchStates.get(batchIndex);
|
|
157
|
-
if (currentState !== "failed") {
|
|
158
|
-
this.batchStates.set(batchIndex, "completed");
|
|
159
|
-
}
|
|
160
|
-
// Move from reserved to used (assuming the tokens were actually used)
|
|
161
|
-
this.reservedTokens -= allocated;
|
|
162
|
-
this.usedTokens += allocated;
|
|
163
|
-
this.batchAllocations.delete(batchIndex);
|
|
164
|
-
// Clean up pre-allocation tracking
|
|
165
|
-
if (this.preAllocationMode) {
|
|
166
|
-
this.preAllocatedBatches.delete(batchIndex);
|
|
167
|
-
}
|
|
168
|
-
logger.debug(`Released ${allocated} tokens from batch ${batchIndex} ` +
|
|
169
|
-
`(${this.getAvailableBudget()} now available)`);
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Get the available token budget (not yet allocated or used)
|
|
173
|
-
*/
|
|
174
|
-
getAvailableBudget() {
|
|
175
|
-
return this.totalBudget - this.usedTokens - this.reservedTokens;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Get the total token budget
|
|
179
|
-
*/
|
|
180
|
-
getTotalBudget() {
|
|
181
|
-
return this.totalBudget;
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Get the number of tokens actually used (completed batches)
|
|
185
|
-
*/
|
|
186
|
-
getUsedTokens() {
|
|
187
|
-
return this.usedTokens;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Get the number of tokens reserved (allocated but not yet used)
|
|
191
|
-
*/
|
|
192
|
-
getReservedTokens() {
|
|
193
|
-
return this.reservedTokens;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Get the number of active batch allocations
|
|
197
|
-
*/
|
|
198
|
-
getActiveBatches() {
|
|
199
|
-
return this.batchAllocations.size;
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Get detailed budget status for monitoring
|
|
203
|
-
*/
|
|
204
|
-
getBudgetStatus() {
|
|
205
|
-
const utilizationPercent = ((this.usedTokens + this.reservedTokens) / this.totalBudget) * 100;
|
|
206
|
-
return {
|
|
207
|
-
total: this.totalBudget,
|
|
208
|
-
used: this.usedTokens,
|
|
209
|
-
reserved: this.reservedTokens,
|
|
210
|
-
available: this.getAvailableBudget(),
|
|
211
|
-
activeBatches: this.batchAllocations.size,
|
|
212
|
-
utilizationPercent: Math.round(utilizationPercent * 100) / 100,
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Reset the budget manager (for testing or reuse)
|
|
217
|
-
*/
|
|
218
|
-
reset() {
|
|
219
|
-
this.usedTokens = 0;
|
|
220
|
-
this.reservedTokens = 0;
|
|
221
|
-
this.batchAllocations.clear();
|
|
222
|
-
logger.debug("TokenBudgetManager reset");
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Pre-allocate tokens for all batches upfront
|
|
226
|
-
* This ensures all batches have guaranteed token allocation before processing starts
|
|
227
|
-
*/
|
|
228
|
-
preAllocateAllBatches(allocations) {
|
|
229
|
-
const totalRequired = Array.from(allocations.values()).reduce((sum, tokens) => sum + tokens, 0);
|
|
230
|
-
if (totalRequired > this.totalBudget) {
|
|
231
|
-
logger.error(`Pre-allocation failed: total required (${totalRequired}) exceeds budget (${this.totalBudget})`);
|
|
232
|
-
return false;
|
|
233
|
-
}
|
|
234
|
-
// Clear any existing allocations and reset state
|
|
235
|
-
this.batchAllocations.clear();
|
|
236
|
-
this.reservedTokens = 0;
|
|
237
|
-
this.batchStates.clear();
|
|
238
|
-
this.preAllocatedBatches.clear();
|
|
239
|
-
// Enable pre-allocation mode
|
|
240
|
-
this.preAllocationMode = true;
|
|
241
|
-
// Reserve all tokens upfront
|
|
242
|
-
allocations.forEach((tokens, batchIndex) => {
|
|
243
|
-
this.batchAllocations.set(batchIndex, tokens);
|
|
244
|
-
this.reservedTokens += tokens;
|
|
245
|
-
this.preAllocatedBatches.add(batchIndex);
|
|
246
|
-
this.batchStates.set(batchIndex, "pending");
|
|
247
|
-
});
|
|
248
|
-
logger.info(`Pre-allocated ${totalRequired} tokens across ${allocations.size} batches ` +
|
|
249
|
-
`(${this.getAvailableBudget()} remaining)`);
|
|
250
|
-
return true;
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Mark a batch as failed and handle cleanup
|
|
254
|
-
*/
|
|
255
|
-
markBatchFailed(batchIndex, error) {
|
|
256
|
-
this.batchStates.set(batchIndex, "failed");
|
|
257
|
-
if (error) {
|
|
258
|
-
logger.debug(`Batch ${batchIndex} marked as failed: ${error}`);
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
logger.debug(`Batch ${batchIndex} marked as failed`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Get the current state of a batch
|
|
266
|
-
*/
|
|
267
|
-
getBatchState(batchIndex) {
|
|
268
|
-
return this.batchStates.get(batchIndex);
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Check if pre-allocation mode is active
|
|
272
|
-
*/
|
|
273
|
-
isPreAllocationMode() {
|
|
274
|
-
return this.preAllocationMode;
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Get all batch states for debugging
|
|
278
|
-
*/
|
|
279
|
-
getAllBatchStates() {
|
|
280
|
-
return new Map(this.batchStates);
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Disable pre-allocation mode and clean up
|
|
284
|
-
*/
|
|
285
|
-
disablePreAllocationMode() {
|
|
286
|
-
this.preAllocationMode = false;
|
|
287
|
-
this.preAllocatedBatches.clear();
|
|
288
|
-
logger.debug("Pre-allocation mode disabled");
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Update the total budget (useful for dynamic adjustment)
|
|
292
|
-
*/
|
|
293
|
-
updateBudget(newBudget) {
|
|
294
|
-
if (newBudget <= 0) {
|
|
295
|
-
throw new Error("Token budget must be greater than 0");
|
|
296
|
-
}
|
|
297
|
-
const oldBudget = this.totalBudget;
|
|
298
|
-
this.totalBudget = newBudget;
|
|
299
|
-
logger.debug(`Token budget updated from ${oldBudget} to ${newBudget}`);
|
|
300
|
-
// Log warning if new budget is less than current usage
|
|
301
|
-
if (newBudget < this.usedTokens + this.reservedTokens) {
|
|
302
|
-
logger.warn(`New budget (${newBudget}) is less than current usage (${this.usedTokens + this.reservedTokens})`);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Factory function to create a Semaphore with validation
|
|
308
|
-
*/
|
|
309
|
-
export function createSemaphore(permits) {
|
|
310
|
-
return new Semaphore(permits);
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Factory function to create a TokenBudgetManager with validation
|
|
314
|
-
*/
|
|
315
|
-
export function createTokenBudgetManager(totalBudget) {
|
|
316
|
-
return new TokenBudgetManager(totalBudget);
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Utility function to calculate optimal concurrency based on available resources
|
|
320
|
-
*/
|
|
321
|
-
export function calculateOptimalConcurrency(totalBatches, maxConcurrent, averageTokensPerBatch, totalTokenBudget) {
|
|
322
|
-
// Don't exceed the configured maximum
|
|
323
|
-
let optimal = Math.min(maxConcurrent, totalBatches);
|
|
324
|
-
// Don't exceed what the token budget can support
|
|
325
|
-
const tokenBasedLimit = Math.floor(totalTokenBudget / averageTokensPerBatch);
|
|
326
|
-
optimal = Math.min(optimal, tokenBasedLimit);
|
|
327
|
-
// Ensure at least 1
|
|
328
|
-
optimal = Math.max(1, optimal);
|
|
329
|
-
logger.debug(`Calculated optimal concurrency: ${optimal} ` +
|
|
330
|
-
`(max: ${maxConcurrent}, batches: ${totalBatches}, token-limited: ${tokenBasedLimit})`);
|
|
331
|
-
return optimal;
|
|
332
|
-
}
|
|
333
|
-
//# sourceMappingURL=ParallelProcessing.js.map
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider Token Limits Utility
|
|
3
|
-
* Centralized management of AI provider token limits and validation
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* AI Provider types supported by the system
|
|
7
|
-
*/
|
|
8
|
-
export type AIProvider = 'vertex' | 'google-ai' | 'gemini' | 'openai' | 'gpt-4' | 'anthropic' | 'claude' | 'azure' | 'bedrock' | 'auto';
|
|
9
|
-
/**
|
|
10
|
-
* Provider token limits configuration
|
|
11
|
-
* These limits are conservative values to avoid API errors
|
|
12
|
-
*/
|
|
13
|
-
export declare const PROVIDER_TOKEN_LIMITS: Record<AIProvider, number>;
|
|
14
|
-
/**
|
|
15
|
-
* Conservative limits used by CodeReviewer for safety
|
|
16
|
-
* These are slightly lower than the actual limits to provide buffer
|
|
17
|
-
*/
|
|
18
|
-
export declare const CONSERVATIVE_PROVIDER_LIMITS: Record<AIProvider, number>;
|
|
19
|
-
/**
|
|
20
|
-
* Get the token limit for a specific provider
|
|
21
|
-
* @param provider - The AI provider name
|
|
22
|
-
* @param conservative - Whether to use conservative limits (default: false)
|
|
23
|
-
* @returns The token limit for the provider
|
|
24
|
-
*/
|
|
25
|
-
export declare function getProviderTokenLimit(provider: string, conservative?: boolean): number;
|
|
26
|
-
/**
|
|
27
|
-
* Validate and adjust token limit for a provider
|
|
28
|
-
* @param provider - The AI provider name
|
|
29
|
-
* @param configuredTokens - The configured token limit
|
|
30
|
-
* @param conservative - Whether to use conservative limits (default: false)
|
|
31
|
-
* @returns The validated and potentially adjusted token limit
|
|
32
|
-
*/
|
|
33
|
-
export declare function validateProviderTokenLimit(provider: string, configuredTokens: number | undefined, conservative?: boolean): number;
|
|
34
|
-
/**
|
|
35
|
-
* Get all supported providers
|
|
36
|
-
* @returns Array of supported provider names
|
|
37
|
-
*/
|
|
38
|
-
export declare function getSupportedProviders(): AIProvider[];
|
|
39
|
-
/**
|
|
40
|
-
* Check if a provider is supported
|
|
41
|
-
* @param provider - The provider name to check
|
|
42
|
-
* @returns True if the provider is supported
|
|
43
|
-
*/
|
|
44
|
-
export declare function isProviderSupported(provider: string): boolean;
|
|
45
|
-
/**
|
|
46
|
-
* Get provider information including limits and support status
|
|
47
|
-
* @param provider - The provider name
|
|
48
|
-
* @param conservative - Whether to use conservative limits
|
|
49
|
-
* @returns Provider information object
|
|
50
|
-
*/
|
|
51
|
-
export declare function getProviderInfo(provider: string, conservative?: boolean): {
|
|
52
|
-
provider: string;
|
|
53
|
-
isSupported: boolean;
|
|
54
|
-
tokenLimit: number;
|
|
55
|
-
conservativeLimit: number;
|
|
56
|
-
standardLimit: number;
|
|
57
|
-
};
|
|
58
|
-
//# sourceMappingURL=ProviderLimits.d.ts.map
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider Token Limits Utility
|
|
3
|
-
* Centralized management of AI provider token limits and validation
|
|
4
|
-
*/
|
|
5
|
-
import { logger } from "./Logger.js";
|
|
6
|
-
/**
|
|
7
|
-
* Provider token limits configuration
|
|
8
|
-
* These limits are conservative values to avoid API errors
|
|
9
|
-
*/
|
|
10
|
-
export const PROVIDER_TOKEN_LIMITS = {
|
|
11
|
-
// Google/Vertex AI providers
|
|
12
|
-
'vertex': 65536, // Vertex AI limit is 65537 exclusive = 65536 max
|
|
13
|
-
'google-ai': 65536, // Google AI Studio limit
|
|
14
|
-
'gemini': 65536, // Gemini model limit
|
|
15
|
-
// OpenAI providers
|
|
16
|
-
'openai': 128000, // OpenAI GPT-4 and newer models
|
|
17
|
-
'gpt-4': 128000, // GPT-4 specific limit
|
|
18
|
-
// Anthropic providers
|
|
19
|
-
'anthropic': 200000, // Claude models limit
|
|
20
|
-
'claude': 200000, // Claude specific limit
|
|
21
|
-
// Microsoft Azure
|
|
22
|
-
'azure': 128000, // Azure OpenAI limit
|
|
23
|
-
// AWS Bedrock
|
|
24
|
-
'bedrock': 100000, // AWS Bedrock limit
|
|
25
|
-
// Auto-selection mode (conservative default)
|
|
26
|
-
'auto': 60000, // Conservative default for auto-selection
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* Conservative limits used by CodeReviewer for safety
|
|
30
|
-
* These are slightly lower than the actual limits to provide buffer
|
|
31
|
-
*/
|
|
32
|
-
export const CONSERVATIVE_PROVIDER_LIMITS = {
|
|
33
|
-
'vertex': 65536,
|
|
34
|
-
'google-ai': 65536,
|
|
35
|
-
'gemini': 65536,
|
|
36
|
-
'openai': 120000, // Slightly lower for safety
|
|
37
|
-
'gpt-4': 120000,
|
|
38
|
-
'anthropic': 190000, // Slightly lower for safety
|
|
39
|
-
'claude': 190000,
|
|
40
|
-
'azure': 120000,
|
|
41
|
-
'bedrock': 95000, // Significantly lower for safety
|
|
42
|
-
'auto': 60000,
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* Get the token limit for a specific provider
|
|
46
|
-
* @param provider - The AI provider name
|
|
47
|
-
* @param conservative - Whether to use conservative limits (default: false)
|
|
48
|
-
* @returns The token limit for the provider
|
|
49
|
-
*/
|
|
50
|
-
export function getProviderTokenLimit(provider, conservative = false) {
|
|
51
|
-
// Handle null, undefined, or empty string
|
|
52
|
-
if (!provider || typeof provider !== 'string') {
|
|
53
|
-
return conservative ? CONSERVATIVE_PROVIDER_LIMITS.auto : PROVIDER_TOKEN_LIMITS.auto;
|
|
54
|
-
}
|
|
55
|
-
const normalizedProvider = provider.toLowerCase();
|
|
56
|
-
const limits = conservative ? CONSERVATIVE_PROVIDER_LIMITS : PROVIDER_TOKEN_LIMITS;
|
|
57
|
-
// Handle empty string after normalization
|
|
58
|
-
if (normalizedProvider === '') {
|
|
59
|
-
return conservative ? CONSERVATIVE_PROVIDER_LIMITS.auto : PROVIDER_TOKEN_LIMITS.auto;
|
|
60
|
-
}
|
|
61
|
-
// Direct match
|
|
62
|
-
if (normalizedProvider in limits) {
|
|
63
|
-
return limits[normalizedProvider];
|
|
64
|
-
}
|
|
65
|
-
// Partial match - check if provider contains any known provider name
|
|
66
|
-
for (const [key, limit] of Object.entries(limits)) {
|
|
67
|
-
if (normalizedProvider.includes(key) || key.includes(normalizedProvider)) {
|
|
68
|
-
return limit;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// Default fallback
|
|
72
|
-
return conservative ? CONSERVATIVE_PROVIDER_LIMITS.auto : PROVIDER_TOKEN_LIMITS.auto;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Validate and adjust token limit for a provider
|
|
76
|
-
* @param provider - The AI provider name
|
|
77
|
-
* @param configuredTokens - The configured token limit
|
|
78
|
-
* @param conservative - Whether to use conservative limits (default: false)
|
|
79
|
-
* @returns The validated and potentially adjusted token limit
|
|
80
|
-
*/
|
|
81
|
-
export function validateProviderTokenLimit(provider, configuredTokens, conservative = false) {
|
|
82
|
-
const providerLimit = getProviderTokenLimit(provider, conservative);
|
|
83
|
-
if (!configuredTokens || configuredTokens <= 0) {
|
|
84
|
-
logger.debug(`No configured tokens for ${provider}, using provider default: ${providerLimit}`);
|
|
85
|
-
return providerLimit;
|
|
86
|
-
}
|
|
87
|
-
if (configuredTokens > providerLimit) {
|
|
88
|
-
logger.warn(`Configured maxTokens (${configuredTokens}) exceeds ${provider} limit (${providerLimit}). Adjusting to ${providerLimit}.`);
|
|
89
|
-
return providerLimit;
|
|
90
|
-
}
|
|
91
|
-
logger.debug(`Token limit validation passed: ${configuredTokens} <= ${providerLimit} for provider ${provider}`);
|
|
92
|
-
return configuredTokens;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Get all supported providers
|
|
96
|
-
* @returns Array of supported provider names
|
|
97
|
-
*/
|
|
98
|
-
export function getSupportedProviders() {
|
|
99
|
-
return Object.keys(PROVIDER_TOKEN_LIMITS);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Check if a provider is supported
|
|
103
|
-
* @param provider - The provider name to check
|
|
104
|
-
* @returns True if the provider is supported
|
|
105
|
-
*/
|
|
106
|
-
export function isProviderSupported(provider) {
|
|
107
|
-
// Handle null, undefined, or empty string
|
|
108
|
-
if (!provider || typeof provider !== 'string') {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
const normalizedProvider = provider.toLowerCase();
|
|
112
|
-
// Handle empty string after normalization
|
|
113
|
-
if (normalizedProvider === '') {
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
// Check direct match
|
|
117
|
-
if (normalizedProvider in PROVIDER_TOKEN_LIMITS) {
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
// Check partial match
|
|
121
|
-
for (const key of Object.keys(PROVIDER_TOKEN_LIMITS)) {
|
|
122
|
-
if (normalizedProvider.includes(key) || key.includes(normalizedProvider)) {
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Get provider information including limits and support status
|
|
130
|
-
* @param provider - The provider name
|
|
131
|
-
* @param conservative - Whether to use conservative limits
|
|
132
|
-
* @returns Provider information object
|
|
133
|
-
*/
|
|
134
|
-
export function getProviderInfo(provider, conservative = false) {
|
|
135
|
-
return {
|
|
136
|
-
provider,
|
|
137
|
-
isSupported: isProviderSupported(provider),
|
|
138
|
-
tokenLimit: getProviderTokenLimit(provider, conservative),
|
|
139
|
-
conservativeLimit: getProviderTokenLimit(provider, true),
|
|
140
|
-
standardLimit: getProviderTokenLimit(provider, false),
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
//# sourceMappingURL=ProviderLimits.js.map
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Retry Manager for Yama
|
|
3
|
-
* Provides intelligent retry logic with exponential backoff for handling transient failures
|
|
4
|
-
*/
|
|
5
|
-
export interface RetryOptions {
|
|
6
|
-
maxAttempts?: number;
|
|
7
|
-
baseDelayMs?: number;
|
|
8
|
-
maxDelayMs?: number;
|
|
9
|
-
backoffMultiplier?: number;
|
|
10
|
-
jitterMs?: number;
|
|
11
|
-
retryableErrors?: string[];
|
|
12
|
-
}
|
|
13
|
-
export interface RetryContext {
|
|
14
|
-
operation: string;
|
|
15
|
-
attempt: number;
|
|
16
|
-
maxAttempts: number;
|
|
17
|
-
lastError?: Error;
|
|
18
|
-
totalElapsed: number;
|
|
19
|
-
}
|
|
20
|
-
export declare class RetryManager {
|
|
21
|
-
private static readonly DEFAULT_OPTIONS;
|
|
22
|
-
/**
|
|
23
|
-
* Execute an operation with retry logic
|
|
24
|
-
*/
|
|
25
|
-
static withRetry<T>(operation: () => Promise<T>, context: string, options?: RetryOptions): Promise<T>;
|
|
26
|
-
/**
|
|
27
|
-
* Check if an error is retryable based on error patterns
|
|
28
|
-
*/
|
|
29
|
-
private static isRetryableError;
|
|
30
|
-
/**
|
|
31
|
-
* Calculate delay with exponential backoff and jitter
|
|
32
|
-
*/
|
|
33
|
-
private static calculateDelay;
|
|
34
|
-
/**
|
|
35
|
-
* Sleep for specified milliseconds
|
|
36
|
-
*/
|
|
37
|
-
private static sleep;
|
|
38
|
-
/**
|
|
39
|
-
* Create a retry wrapper function for a specific operation
|
|
40
|
-
*/
|
|
41
|
-
static createRetryWrapper<T extends any[], R>(fn: (...args: T) => Promise<R>, context: string, options?: RetryOptions): (...args: T) => Promise<R>;
|
|
42
|
-
/**
|
|
43
|
-
* Batch retry operations with individual retry logic
|
|
44
|
-
*/
|
|
45
|
-
static batchWithRetry<T>(operations: Array<{
|
|
46
|
-
fn: () => Promise<T>;
|
|
47
|
-
context: string;
|
|
48
|
-
}>, options?: RetryOptions & {
|
|
49
|
-
continueOnError?: boolean;
|
|
50
|
-
}): Promise<Array<{
|
|
51
|
-
success: boolean;
|
|
52
|
-
data?: T;
|
|
53
|
-
error?: Error;
|
|
54
|
-
context: string;
|
|
55
|
-
}>>;
|
|
56
|
-
/**
|
|
57
|
-
* Get retry statistics for monitoring
|
|
58
|
-
*/
|
|
59
|
-
static getRetryStats(results: Array<{
|
|
60
|
-
success: boolean;
|
|
61
|
-
context: string;
|
|
62
|
-
}>): {
|
|
63
|
-
total: number;
|
|
64
|
-
successful: number;
|
|
65
|
-
failed: number;
|
|
66
|
-
successRate: number;
|
|
67
|
-
failuresByContext: Record<string, number>;
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* Create a circuit breaker pattern (simple implementation)
|
|
71
|
-
*/
|
|
72
|
-
static createCircuitBreaker<T extends any[], R>(fn: (...args: T) => Promise<R>, context: string, options?: {
|
|
73
|
-
failureThreshold?: number;
|
|
74
|
-
recoveryTimeoutMs?: number;
|
|
75
|
-
retryOptions?: RetryOptions;
|
|
76
|
-
}): (...args: T) => Promise<R>;
|
|
77
|
-
}
|
|
78
|
-
//# sourceMappingURL=RetryManager.d.ts.map
|