minovative-mind-cli 2.8.0 ā 2.8.1
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/dist/services/agent.js
CHANGED
|
@@ -26,7 +26,7 @@ import { markedTerminal } from 'marked-terminal';
|
|
|
26
26
|
const execAsync = promisify(exec);
|
|
27
27
|
import { debugLog, isDebugOn } from '../utils/logger.js';
|
|
28
28
|
import { ensureProjectStorage, ensureIgnored, readCache, writeCache, invalidateCacheForDependents, } from '../utils/projectStorage.js';
|
|
29
|
-
import { GEMINI_MODELS, isByokEnabled } from '../utils/config.js';
|
|
29
|
+
import { GEMINI_MODELS, isByokEnabled, TPM_COOLING_DELAYS } from '../utils/config.js';
|
|
30
30
|
import { createSharedChatSession, getGeneralChatConfig, getPlanExecutionConfig, compressTextUsingFlashLite, generateChatTitle, getGlobalActiveModel, setGlobalActiveModel, summarizeChatHistory, } from './ai.js';
|
|
31
31
|
import { getAndResetTurnUsage } from './proxyClient.js';
|
|
32
32
|
import { changeLogger } from './changeLogger.js';
|
|
@@ -317,6 +317,8 @@ export async function executeSingleTurn(workspaceRoot, userInput, chat, inputHan
|
|
|
317
317
|
inputHandler.start(spinner);
|
|
318
318
|
changeLogger.startChangeSet(userInput);
|
|
319
319
|
let finalInput = userInput;
|
|
320
|
+
// Inter-turn cooling-off delay to allow API token buckets to settle before running intent routing
|
|
321
|
+
await new Promise((resolve) => setTimeout(resolve, TPM_COOLING_DELAYS.INTER_TURN_MS));
|
|
320
322
|
// Stage 0: Summarize chat history if length threshold is met
|
|
321
323
|
if (!cachedContextResult) {
|
|
322
324
|
const isDebug = isDebugOn();
|
|
@@ -359,6 +361,8 @@ export async function executeSingleTurn(workspaceRoot, userInput, chat, inputHan
|
|
|
359
361
|
toolLogs.forEach((log) => p.log.step(log));
|
|
360
362
|
spinner.start(`š Context gathered successfully.`);
|
|
361
363
|
}
|
|
364
|
+
// Post-investigation cooling-off delay to allow API Tokens-Per-Minute (TPM) sliding window to settle
|
|
365
|
+
await new Promise((resolve) => setTimeout(resolve, TPM_COOLING_DELAYS.POST_INVESTIGATION_MS));
|
|
362
366
|
}
|
|
363
367
|
let latestUsage = undefined;
|
|
364
368
|
// Collect any inputs that were queued while the Context Agent was investigating
|
|
@@ -481,7 +485,8 @@ export async function executeSingleTurn(workspaceRoot, userInput, chat, inputHan
|
|
|
481
485
|
modifiedFiles.forEach((file) => p.log.message(` ${pc.dim('ā¢')} ${file}`));
|
|
482
486
|
}
|
|
483
487
|
else {
|
|
484
|
-
summaryMsg =
|
|
488
|
+
summaryMsg =
|
|
489
|
+
'Generation was stopped by the user before completion. No code files were modified before stopping.';
|
|
485
490
|
p.log.warn(pc.yellow('\nā ļø Generation stopped by user before completion (no files were modified).'));
|
|
486
491
|
}
|
|
487
492
|
chat.addTurn({
|
|
@@ -657,8 +662,7 @@ export async function executeSingleTurn(workspaceRoot, userInput, chat, inputHan
|
|
|
657
662
|
const turnDuration = ((turnEndTime - turnStartTime) / 1000).toFixed(1);
|
|
658
663
|
p.log.info(`${pc.dim('Generated in')} ${pc.cyan(turnDuration + 's')}`);
|
|
659
664
|
// Check if generation was stopped by user
|
|
660
|
-
const isStopped = finalText.includes('Generation stopped') ||
|
|
661
|
-
finalText.includes('[Generation stopped');
|
|
665
|
+
const isStopped = finalText.includes('Generation stopped') || finalText.includes('[Generation stopped');
|
|
662
666
|
if (isStopped) {
|
|
663
667
|
const currentChanges = changeLogger.getCurrentChangeSet()?.changes || [];
|
|
664
668
|
const modifiedFiles = currentChanges
|
|
@@ -672,7 +676,8 @@ export async function executeSingleTurn(workspaceRoot, userInput, chat, inputHan
|
|
|
672
676
|
modifiedFiles.forEach((file) => p.log.message(` ${pc.dim('ā¢')} ${file}`));
|
|
673
677
|
}
|
|
674
678
|
else {
|
|
675
|
-
summaryMsg =
|
|
679
|
+
summaryMsg =
|
|
680
|
+
'Generation was stopped by the user before completion. No code files were modified before stopping.';
|
|
676
681
|
p.log.warn(pc.yellow('\nā ļø Generation stopped by user before completion (no files were modified).'));
|
|
677
682
|
}
|
|
678
683
|
chat.addTurn({
|
|
@@ -25,6 +25,7 @@ import { InvestigationAgentRunner } from './investigationAgent.js';
|
|
|
25
25
|
import { readFile } from '../agent-tools.js';
|
|
26
26
|
import { buildDependencyGraph } from '../../utils/dependencyTracer.js';
|
|
27
27
|
import { debugLog } from '../../utils/logger.js';
|
|
28
|
+
import { TPM_COOLING_DELAYS } from '../../utils/config.js';
|
|
28
29
|
// āāā Constants āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
29
30
|
/** Maximum total relevant files across all agents after merge. */
|
|
30
31
|
const MAX_TOTAL_FILES = 30;
|
|
@@ -57,6 +58,8 @@ export class InvestigationOrchestrator {
|
|
|
57
58
|
const agents = agentAssignments.map((assignment) => new InvestigationAgentRunner(assignment.agentLabel, assignment.domains, workspaceRoot, readCache, projectTree, projectType));
|
|
58
59
|
// 3. Run all agents in parallel
|
|
59
60
|
const startTime = Date.now();
|
|
61
|
+
// Cooling-off pause to prevent burst 429 errors when initiating parallel agent dispatch
|
|
62
|
+
await new Promise((resolve) => setTimeout(resolve, TPM_COOLING_DELAYS.PARALLEL_DISPATCH_MS));
|
|
60
63
|
// Limit parallel investigation agents to 2 to avoid Vertex AI RESOURCE_EXHAUSTED errors
|
|
61
64
|
const MAX_CONCURRENT = 2;
|
|
62
65
|
const results = [];
|
|
@@ -41,7 +41,7 @@ let globalSessionAccumulatedUsage = {
|
|
|
41
41
|
totalTokenCount: 0,
|
|
42
42
|
creditsUsed: 0,
|
|
43
43
|
remainingBalance: undefined,
|
|
44
|
-
modelsUsed: {}
|
|
44
|
+
modelsUsed: {},
|
|
45
45
|
};
|
|
46
46
|
export function getAndResetTurnUsage() {
|
|
47
47
|
const current = { ...globalSessionAccumulatedUsage };
|
|
@@ -52,7 +52,7 @@ export function getAndResetTurnUsage() {
|
|
|
52
52
|
totalTokenCount: 0,
|
|
53
53
|
creditsUsed: 0,
|
|
54
54
|
remainingBalance: undefined,
|
|
55
|
-
modelsUsed: {}
|
|
55
|
+
modelsUsed: {},
|
|
56
56
|
};
|
|
57
57
|
return current;
|
|
58
58
|
}
|
|
@@ -117,6 +117,7 @@ export class ProxyClient {
|
|
|
117
117
|
if ((response.status === 429 || response.status === 503) && attempt < MAX_RETRIES) {
|
|
118
118
|
const exponentialDelay = Math.min(MAX_DELAY_MS, BASE_DELAY_MS * Math.pow(2, attempt));
|
|
119
119
|
const delayTime = Math.round(exponentialDelay * (0.5 + Math.random() * 0.5));
|
|
120
|
+
process.stdout.write('\n');
|
|
120
121
|
console.warn(`Rate limit or service unavailable hit (${response.status}). Retrying in ${(delayTime / 1000).toFixed(1)}s... (Attempt ${attempt + 1}/${MAX_RETRIES})`);
|
|
121
122
|
await delay(delayTime, abortSignal);
|
|
122
123
|
attempt++;
|
|
@@ -198,7 +199,7 @@ export class ProxyClient {
|
|
|
198
199
|
collector?.accumulateUsage({
|
|
199
200
|
promptTokens: data.usage.promptTokens || 0,
|
|
200
201
|
candidatesTokens: data.usage.candidatesTokens || 0,
|
|
201
|
-
cachedTokens: data.usage.cachedTokens || 0
|
|
202
|
+
cachedTokens: data.usage.cachedTokens || 0,
|
|
202
203
|
});
|
|
203
204
|
globalSessionAccumulatedUsage.promptTokens += data.usage.promptTokens || 0;
|
|
204
205
|
globalSessionAccumulatedUsage.candidatesTokens += data.usage.candidatesTokens || 0;
|
|
@@ -209,7 +210,8 @@ export class ProxyClient {
|
|
|
209
210
|
if (data.usage.remainingBalance !== undefined) {
|
|
210
211
|
globalSessionAccumulatedUsage.remainingBalance = data.usage.remainingBalance;
|
|
211
212
|
}
|
|
212
|
-
globalSessionAccumulatedUsage.modelsUsed[modelName] =
|
|
213
|
+
globalSessionAccumulatedUsage.modelsUsed[modelName] =
|
|
214
|
+
(globalSessionAccumulatedUsage.modelsUsed[modelName] || 0) + 1;
|
|
213
215
|
}
|
|
214
216
|
if (data.groundingMetadata) {
|
|
215
217
|
groundingMetadata = data.groundingMetadata;
|
|
@@ -236,6 +238,7 @@ export class ProxyClient {
|
|
|
236
238
|
if (attempt < MAX_RETRIES) {
|
|
237
239
|
const exponentialDelay = Math.min(MAX_DELAY_MS, BASE_DELAY_MS * Math.pow(2, attempt));
|
|
238
240
|
const delayTime = Math.round(exponentialDelay * (0.5 + Math.random() * 0.5));
|
|
241
|
+
process.stdout.write('\n');
|
|
239
242
|
console.warn(`Rate limit or service unavailable hit during stream. Retrying in ${(delayTime / 1000).toFixed(1)}s... (Attempt ${attempt + 1}/${MAX_RETRIES})`);
|
|
240
243
|
await delay(delayTime, abortSignal);
|
|
241
244
|
attempt++;
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -25,6 +25,19 @@ export declare const GEMINI_MODELS: {
|
|
|
25
25
|
export declare const DEFAULT_MODEL: "auto";
|
|
26
26
|
/** Maximum tokens the model can output per response. */
|
|
27
27
|
export declare const MAX_OUTPUT_TOKENS = 60000;
|
|
28
|
+
/**
|
|
29
|
+
* Rate limit & Tokens-Per-Minute (TPM) cooling-off delays (in milliseconds).
|
|
30
|
+
* Prevents transient 429 / 503 rate-limit errors by giving the API 60-second
|
|
31
|
+
* rolling token window time to settle during key agent transitions.
|
|
32
|
+
*/
|
|
33
|
+
export declare const TPM_COOLING_DELAYS: {
|
|
34
|
+
/** Pause before running initial intent routing between turns */
|
|
35
|
+
readonly INTER_TURN_MS: 1000;
|
|
36
|
+
/** Pause before dispatching parallel sub-agent investigations simultaneously */
|
|
37
|
+
readonly PARALLEL_DISPATCH_MS: 1000;
|
|
38
|
+
/** Pause after context gathering completes before starting the execution stream */
|
|
39
|
+
readonly POST_INVESTIGATION_MS: 3000;
|
|
40
|
+
};
|
|
28
41
|
/**
|
|
29
42
|
* Checks if BYOK is currently enabled for the user.
|
|
30
43
|
*/
|
package/dist/utils/config.js
CHANGED
|
@@ -25,6 +25,19 @@ export const GEMINI_MODELS = {
|
|
|
25
25
|
export const DEFAULT_MODEL = GEMINI_MODELS.AUTO;
|
|
26
26
|
/** Maximum tokens the model can output per response. */
|
|
27
27
|
export const MAX_OUTPUT_TOKENS = 60_000;
|
|
28
|
+
/**
|
|
29
|
+
* Rate limit & Tokens-Per-Minute (TPM) cooling-off delays (in milliseconds).
|
|
30
|
+
* Prevents transient 429 / 503 rate-limit errors by giving the API 60-second
|
|
31
|
+
* rolling token window time to settle during key agent transitions.
|
|
32
|
+
*/
|
|
33
|
+
export const TPM_COOLING_DELAYS = {
|
|
34
|
+
/** Pause before running initial intent routing between turns */
|
|
35
|
+
INTER_TURN_MS: 1000,
|
|
36
|
+
/** Pause before dispatching parallel sub-agent investigations simultaneously */
|
|
37
|
+
PARALLEL_DISPATCH_MS: 1000,
|
|
38
|
+
/** Pause after context gathering completes before starting the execution stream */
|
|
39
|
+
POST_INVESTIGATION_MS: 3000,
|
|
40
|
+
};
|
|
28
41
|
/**
|
|
29
42
|
* Checks if BYOK is currently enabled for the user.
|
|
30
43
|
*/
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minovative-mind-cli",
|
|
3
3
|
"description": "An automated AI agent powered by Vertex AI that helps you write software",
|
|
4
|
-
"version": "2.8.
|
|
4
|
+
"version": "2.8.1",
|
|
5
5
|
"author": "Daniel Ward",
|
|
6
6
|
"bin": {
|
|
7
7
|
"minovative-mind-cli": "bin/run.js"
|
|
@@ -78,9 +78,8 @@
|
|
|
78
78
|
"scripts": {
|
|
79
79
|
"build": "shx rm -rf dist tsconfig.tsbuildinfo && tsc -b",
|
|
80
80
|
"prepare": "npm run build",
|
|
81
|
-
"lint": "eslint",
|
|
81
|
+
"lint": "eslint src/ test/",
|
|
82
82
|
"postpack": "shx rm -f oclif.manifest.json",
|
|
83
|
-
"posttest": "npm run lint",
|
|
84
83
|
"prepack": "npm run build && oclif manifest && oclif readme --no-source-links",
|
|
85
84
|
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
|
|
86
85
|
"version": "oclif readme --no-source-links && git add README.md"
|